Разве наследование Lua не включает метаметоды?

Я пытаюсь реализовать простое наследование в Lua, как это представлено в PIL 16.2. Однако я столкнулся с удивительным поведением: метаметоды, похоже, не наследуются. В следующем примере я создаю класс Point с x а также y члены, и дать ему __add Метаметод. При добавлении экземпляров Point все работает нормально, но если я создаю подкласс и добавляю экземпляры этого, я получаю ошибку.

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)

Я ожидал, что Луа будет искать __add в ChildPointи это вызвало бы ChildPoint"s __index, находя __add в Point, Но этого не происходит.

Почему это не работает, что на самом деле происходит, и (если это правильное поведение, а не просто моя ошибка), как я могу реализовать наследуемые метаметоды в Lua?

1 ответ

Решение

Как объяснил Егор, в этом случае мета-методы должны быть явно скопированы; см. этот ранее SO вопрос для обсуждения той же самой проблемы и возможных решений (выбранный копирует метаметоды).

Другие вопросы по тегам