Shadowjonathan
Shadowjonathan

Reputation: 274

Is this a bug in lua, or a feature unknown to me?

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

Answers (1)

Vlad
Vlad

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

Related Questions