Lua - Fallback Cases of Indexing Metamethods
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 or throws error. In this chapter, we'll explore fallback behavior of indexing metamethods with examples.
Example - Fallback for __index
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
Example - Fallback for __newindex
When we're assigning a key to table, and metatable is having __newindex metamethod implementation, then Lua will call that method instead of directly assigning the value to the table.
But if metatable is not having __newindex metamethod, the Lua simply assigns the value to the table directly. Lua is not throwing any error in such a case.
main.lua
-- main table
local table1 = {}
-- metatable with missing __newindex field implementation
local metatable1 = {}
-- setmetatable
setmetatable(table1, metatable1)
-- assign new value to table
table1.a = 1
-- prints 1
print(table1.a)
-- define __newindex metamethod to print a mesage instead of assigning a value
metatable1.__newindex = function(table, key, value) print "Ignore assignment" end
-- assign new value to table
table1.b = 2
-- prints nil
print(table.b)
Output
When we run the above program, we will get the following output−
1 Ignore assignment nil