I'm having trouble understanding why there is a difference in behavior of the __index
metamethod between these to examples:
A = { __index = A }
function A:speak()
print("I'm an A")
end
An_A = setmetatable({},A)
An_A:speak()
Will raise the following error: lua: l.lua:8: attempt to call method 'speak' (a nil value)
Whilst
B = { __index = function(t,key) return B[key] end }
function B:speak()
print("I'm an B")
end
An_B = setmetatable({},B)
An_B:speak()
Will perform as expected, outputting I'm an B
.
In trying to understand why this was the case I read this section of PiL. It states that:
The use of the __index metamethod for inheritance is so common that Lua provides a shortcut. Despite the name, the __index metamethod does not need to be a function: It can be a table, instead. When it is a function, Lua calls it with the table and the absent key as its arguments. When it is a table, Lua redoes the access in that table.
My understanding of this is that in the snippet involving 'A', __index = A
cause the access to be done in the table A
(as per the boldened segmenet of the above quote). If this is the case I don't understand why the function associated with the key "speak"
isn't found. In an attempt to try fix this, I decided to implement the function approach in the B
snippet, which returns the value associated with key
in B
, and it worked. Surely __index = A
and (adapted from B
) __index = function(t,key) return A[key] end
have the same effect.
Any clarification would be greatly appreciated.