Search code examples
luametatable

Metatable issue


So I know that lua will look to a table's metatable if it doesn't contain the variable I reference, but it seems wrong that when I attempt to set a variable that doesn't exist yet in a table it sets it in the metatable instead.

Heres an example of what i mean

a = {__index = {tbl1 = {var = 1}, tbl2 = {var = 2}}}
b = setmetatable({}, a)
print(b.tbl1.var, a.__index.tbl1.var)
b.tbl1.var = 2
print(b.tbl1.var, a.__index.tbl1.var)

In this code it will replace the metatables variable instead of setting it in the table im referencing.

However this does not occur with this code

a = {__index = {4, 5, 6}}
b = setmetatable({}, a)
print(b[1], a.__index[1])
b[1] = 2
print(b[1], a.__index[1])

Is there more work needed when using metatables and nested tables? Or is there a way around this?


Solution

  • In this code it will replace the metatables variable instead of setting it in the table im referencing.

    I think this is to be expected; the code retrieves tbl1 key and sets a field in the table associated with that key. The key doesn't exist in the table, only in the metatable, so that's where it's set. If you add the same key in the table b = setmetatable({tbl1 = {}}, a), you'll see that the value is set in that table.

    Is there more work needed when using metatables and nested tables? Or is there a way around this?

    I'm not sure what result you expect. Lua doesn't do autovivification, which would make tbl.foo = 1 to create table tbl if it didn't already exist. If the field tbl1 is already present in the table, the the behavior is exactly what you'd expect. If it's present in the metatable, and you modify its field, this is exactly where it's going to be modified.