lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


We (Lua users at Thermo-Fisher) were surprised recently to find that the __index metamethod of the metatable’s metatable isn’t used when looking for things like __newindex metamethods.

That’s a mouthful, for sure, but suppose we had something like

base={}

setmetatable(base,{__newindex=someusefulthing})


base.__newindex=getmetatable(base).__newindex

 

function base:New()

    self.__index=self

    return setmetatable({},self)

end

 

singlyderived=based:New()

 

instanceofsinglyderived=singlyderived:New()

 

we’d expect a newindex operation for instanceofsinglyderived to look in its metatable (singlyderived) for a __newindex key-value pair.  On not finding it, the __index metamethod would be followed, pointing to base, which has a __newindex that we copied in.  The only place where we have to do any shenanigans is in the base class.


But the search for __newindex doesn’t respect the __index metamethod of the metatable, and the way out is to depart from idiomatic Lua OOP and add something like self.__newindex=getmetatable(self).__newindex in addition to the usual magic “self.__index=self” line.  This isn’t a disaster, but in general any data-structure-like behavior or  any operators (__lt, __gt, etc.) or any other use of the standard metamethods to define object behavior requires explicit propagation, meaning that the inheritance mechanism put forth in PIL and at least somewhat idiomatic in the user community is limited to attributes and methods.

Maybe the performance hit for always respecting the metatable’s metatable is too great?
-Ben Kalafut