I'm trying to implement simple inheritance in Lua as it is presented in PIL 16.2. However, I've come across a surprising behavior: metamethods don't seem to be inherited. In the following example, I create a Point class with x and y members, and give it an __add metamethod. When adding instances of Point, everything works fine, but if I create a subclass and add instances of that, I get an error.
Point = {}
function Point:new(x, y)
local point = {}
setmetatable(point, self)
self.__index = self
point.x = x or 0
point.y = y or 0
return point
end
Point.__add = function(a, b)
return Point:new(a.x + b.x, a.y + b.y)
end
p = Point:new(2,2)
r1 = p + p
print(p.x, p.y) -- prints "4 4" as expected
ChildPoint = Point:new()
c = ChildPoint:new()
r2 = c + c -- Error: attempt to perform arithmetic on a table value (local 't1')
print(r.x, r.y)
I was expecting that Lua would look for __add in ChildPoint, and that would trigger ChildPoint's __index, finding __add in Point. But that does not seem to happen.
Why does this not work, what actually happens, and (if this is correct behavior and not just a mistake of mine) how do I implement inheritable metamethods in Lua?
As Egor explained, the metamethods need to be copied explicitly in this case; see this earlier SO question for the discussion of the same problem and possible solutions (the selected one copies the metamethods).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With