Reputation: 27
The following session shows what I was trying to. I must have misread some documentation somewhere that (I thought) said that an __index item in a metatable provides a default when the table doesn't provide an item for that key. The point is it doesn't work on metatables themselves but I have no idea why not. Where in the documentation is this explained, and what can I do about it in such cases?
Thanks!
> a = {}
> b = {}
> setmetatable(a,b)
table: 0000000002631ae0
> c = { __tostring = function(x) return "X" end }
> setmetatable(b,{ __index=c })
table: 0000000002631560
>
> print(a)
table: 0000000002631ae0
> -- I was expecting: X
> print(getmetatable(a).__tostring)
function: 0000000002633840
> print(tostring(a))
table: 0000000002631ae0
> -- Again, expecting X
> print(getmetatable(a).__tostring(a))
X
>
Here is another example.
> a = {}
> b = {}
> setmetatable(a,b)
table: 0000000002631fe0
> c = { __add = function(x,y) return "X" end }
> setmetatable(b,{ __index=c })
table: 00000000026316a0
>
> print(a+a)
stdin:1: attempt to perform arithmetic on a table value (global 'a')
stack traceback:
stdin:1: in main chunk
[C]: in ?
>
So this problem is not specific to print and tostring. Of course in real situations I want to have a lot of different objects sharing a lot of metatable values without having to copy everything every time...
Upvotes: 2
Views: 786
Reputation: 1762
This is because __index
is related to indexing operations like tbl.var
. Lua doesn't use __index
to get other metamethod (like __tostring
).
You are using print
which invokes __tostring
directly from the metatable, it doesn't use __index
here.
__index: The indexing access operation table[key]
Learn more: https://www.lua.org/manual/5.4/manual.html#2.4
The solution would merging metatable c
with b
.
setmetatable(b,{ __tostring = c.__tostring })
print(b) -- X
Upvotes: 1