Lua - Fallback Mechanisms in Metatables



When any action is performed on a table, Lua first checks if table has information on how to handle such an operation. For example, accessing an existing key, assigning a value, Lua proceeds with default behavior.

In case, table is not having information on operation like arithmetic operation, then Lua will search for the corresponding metamethod in the associated metatable.

Fallback Mechanism

Fallback refers to a condition where a corresponding metamethod is not present in the metatable. In such a case, Lua generally fallbacks to the default behavior for the operation.

Example - Fallback in case of Table Access

  • In case, we try to access a non-existing key in a table, and associated metatable has __index method then Lua will call the __index metamethod.

  • But if metatable is not having __index metamethod, the Lua simply returns nil as fallback. Lua is not throwing any error in such a case.

main.lua

-- main table
local table1 = {a = 1}

-- metatable with missing __index field implementation
local metatable1 = {}

-- setmetatable
setmetatable(table1, metatable1)

-- access non-existing key, prints nil as fallback
print(table1.key)

-- define __index metamethod to get default value as "EMPTY"
metatable1.__index =  function(table, key) return "EMPTY" end

-- access non-existing key again, prints EMPTY
print(table1.key)

Output

When we run the above program, we will get the following output−

nil
EMPTY

Key Considerations about Fallback

  • Silent Failure Handling as Fallback − indexing fields like __index and __newindex fails silently returning nil or assigning a value respectively if corresponding metamethod is not present in the associated metatable.

  • Error as Fallback − Arithmetic, comparison and _call operations on tables fails with error if corresponding metamethods are not available as there is no default behavior available in tables and Lua throws error for such operation on table by default.

  • Default Representation as Fallback − Lua returns a default string representation in case corresponding metamethod is not present.

Advertisements