oopinheritanceluameta-method

Doesn't Lua inheritance include metamethods?


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?


Solution

  • 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).