Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Doesn't Lua inheritance include metamethods? [duplicate]

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?

like image 281
Ludwik Avatar asked Sep 26 '26 04:09

Ludwik


1 Answers

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

like image 117
Paul Kulchenko Avatar answered Sep 28 '26 20:09

Paul Kulchenko