When you try to access a nonexistent field in a table, the result is nil. However, if the table being accessed has a meta table and that meta table has an __index meta method, the meta method will be called.
There are two tables, x and y. Neither table has a hello key, but both tables try to print this key. In both instances, the print statement will result in nil:
x = {
foo = "bar"
}
y = { }
print (x.foo) -- bar
print (x.hello) -- nil
print (y.foo) -- nil
print (y.hello) -- nil
To fix this, create a meta table with an __index meta method. _index takes two arguments. The first argument is the table that is being indexed, the second argument is the key.
The following code creates two meta tables, z and w; both have an __index meta method. Table z uses this meta method to return a variable found in itself, while w manually checks the key and returns some inline string. Table x is assigned the z meta method, table y is assigned the w meta method:
x = {
foo = "bar"
}
y = { }
z = {
hello = "world z",
__index = function(table, key)
return z[key]
end
}
w = {
__index = function(table, key)
if key == "hello" then
return "inline world"
end
return nil
end
}
setmetatable(x, z)
setmetatable(y, w)
print (x.foo) -- bar
print (x.hello) -- world z
print (y.foo) -- nil
print (y.hello) -- inline world
In this code, when printing x.foo, the foo field of the x table is printed. When printing x.hello, Lua sees that table x does not have a hello field, but it does have a meta table and that meta table has an __index function. Lua then passes table x and hello as the arguments to the __index function of the meta table, which returns the hello field of
table z.
When printing y.foo, Lua sees that table y does not have a hello field, but it does have a meta table with an __index meta method. The __index meta method of table w is called, with table y and foo as arguments. This meta method only returns a value if the key provided is hello. Since the key provided is not hello, the __index meta method returns nil.