I've implemented my own class system and I'm having trouble with __tostring
; I suspect a similar issue can happen with other metamethods, but I haven't tried.
(Brief detour: each class has a __classDict
attribute, holding all methods. It is used as the class instances' __index
. At the same time, the __classDict's __index
is the superclass' __classDict
, so methods in superclasses are authomatically looked up.)
I wanted to have a "default tostring" behavior in all instances. But it didn't work: the "tostring" behavior doesn't "propagate" through subclasses correctly.
I've done this test exemplifying my issue:
mt1 = {__tostring=function(x) return x.name or "no name" end }
mt2 = {}
setmetatable(mt2, {__index=mt1})
x = {name='x'}
y = {name='y'}
setmetatable(x, mt1)
setmetatable(y, mt2)
print(x) -- prints "x"
print(mt2.__tostring(y)) -- prints "y"
print(y) -- prints "table: 0x9e84c18" !!
I'd rather have that last line print "y".
Lua's "to_String" behaviour must be using the equivalent of
rawget(instance.class.__classDict, '__tostring')
instead of doing the equivalent of
instance.class.__classDict.__tostring
I suspect the same happens with all metamethods; rawget
-equivalent operations are used.
I guess one thing I could do is copying all the metamethods when I do my subclassing (the equivalent on the above example would be doing mt2.__tostring = mt1.__tostring
) but that is kind of inelegant.
Has anyone fought with this kind of issue? What where your solutions?