2016-03-25 18 views
3

私はLuaで簡単な継承を実装しようとしています。これはPIL 16.2で表されています。しかし、私は驚くべき振る舞いに出くわしました。メタメソッドは継承されていないようです。次の例では、xyメンバーで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で実装するにはどうすればよいですか?

+0

残念ながら、メタメソッドは継承されません(理由はわかりません)。 Luaのマニュアルでは、「メタメソッドのクエリは常に生であり、メタメソッドへのアクセスは他のメタメソッドを呼び出さないことに注意してください。サブクラスを作成するときに、古いメタオブジェクトから新しいインスタンスへのすべての '__ *'メンバーをコピーすることができます(この場合、インスタンスの作成以外のサブクラスを作成する必要があります)。しかし、この解決策は良くありません。 –

答えて

2

Egorが説明したように、この場合、メタメソッドを明示的にコピーする必要があります。同じ問題と考えられる解決策(選択されたものがメタメソッドをコピーする)の議論についてはこれを先にSO questionで見てください。

関連する問題