4

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?

Saana
  • 43
  • 2

1 Answers1

0

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.

Paul Kulchenko
  • 25,884
  • 3
  • 38
  • 56
  • If I use b = setmetatable({tbl1 = {}}, a), it does not inherit the metatables value and instead returns nil which defeats the purpose of the metatable in this context. – Saana Aug 25 '14 at 00:42
  • 1
    That's exactly what you get: if you don't have tbl1 key in your table, you get its default value (from the metatable). If you try to modify values in the table you got based on tbl1 key reference, those will be modified in that table. That's why I asked what you are trying to do or avoid. If you want to avoid modifications to the table stored as value for tbl1 key, you may need to set a metatable on that table. – Paul Kulchenko Aug 25 '14 at 00:45