私はLuaで簡単な継承を実装しようとしています。これはPIL 16.2で表されています。しかし、私は驚くべき振る舞いに出くわしました。メタメソッドは継承されていないようです。次の例では、x
とy
メンバーでPointクラスを作成し、__add
メタメソッドを与えます。 Pointのインスタンスを追加すると、すべて正常に動作しますが、サブクラスを作成してそのインスタンスを追加すると、エラーが発生します。Luaの継承にメタメソッドが含まれていませんか?
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)
私は、LuaはChildPoint
に__add
を探すだろうと期待していた、そしてそれはPoint
で__add
を見つけ、ChildPoint
の__index
をトリガします。しかし、それは起こっていないようです。
なぜ実際には何が起こりますか(これが正しい動作であり、私の間違いではない場合)継承可能なメタメソッドをLuaで実装するにはどうすればよいですか?
残念ながら、メタメソッドは継承されません(理由はわかりません)。 Luaのマニュアルでは、「メタメソッドのクエリは常に生であり、メタメソッドへのアクセスは他のメタメソッドを呼び出さないことに注意してください。サブクラスを作成するときに、古いメタオブジェクトから新しいインスタンスへのすべての '__ *'メンバーをコピーすることができます(この場合、インスタンスの作成以外のサブクラスを作成する必要があります)。しかし、この解決策は良くありません。 –