Reputation: 274
I'm trying to teach a friend of mine how to lua, basically, and he comes to me with this code, and it stumps my head:
a = {name = "aaa"}
function a:new()
self.x = "sss"
o = {}
setmetatable(o, self)
self.__index = self
return o
end
function a:some()
return "[ " .. self.name .. " ]"
end
b = a:new()
print(b:some())
print(b.x)
which prints
[ aaa ]
sss
both shouldnt be possible, since they were never set to o
inside a:new
after some debugging, i look into it, and here some interesting things happen:
a = {name = "aaa", x = "sss"}
function a:new()
o = {}
print(o.x, self.x)
-- nil sss
setmetatable(o, self)
print(o.x, self.x, o, self, self.__index, o.__index)
-- nil sss table: 0x1001280 table: 0x1001320 table: 0x1001320 nil
self.__index = self
print(o.x, self.x, o, self, self.__index, o.__index)
-- sss sss table: 0x1001280 table: 0x1001320 table: 0x1001320 table: 0x1001320
return o
end
Note how on the third print
, it returns the .x
value of self
, but it was called from o
, which has no "relationship" with self, how is this possible?
Upvotes: 4
Views: 192
Reputation: 5902
You've set table a
as __index
field in metatable for all tables that will be created with a:new()
. When some non-existent field will be checked in the b
table, value will be searched in a
too. That's why you can find fields x
or name
in a table b
, even if you didn't assign it explicitly.
Upvotes: 1