__index
これらと例の間でメタメソッドの動作に違いがある理由を理解するのに苦労しています:
A = { __index = A }
function A:speak()
print("I'm an A")
end
An_A = setmetatable({},A)
An_A:speak()
次のエラーが発生します。lua: l.lua:8: attempt to call method 'speak' (a nil value)
一方
B = { __index = function(t,key) return B[key] end }
function B:speak()
print("I'm an B")
end
An_B = setmetatable({},B)
An_B:speak()
期待どおりに実行され、 が出力されI'm an B
ます。
なぜそうなったのかを理解しようとして、PiL のこのセクションを読みました。それは次のように述べています:
継承のための __index メタメソッドの使用は非常に一般的であるため、Lua はショートカットを提供します。名前にもかかわらず、__index メタメソッドは関数である必要はありません。代わりに、テーブルにすることができます。関数の場合、Lua はテーブルと存在しないキーを引数として呼び出します。テーブルの場合、Lua はそのテーブルへのアクセスをやり直します。
これについての私の理解では、「A」を含むスニペットでは__index = A
、アクセスがテーブルで行われるようになっていますA
(上記の引用の太字のセグメントに従って)。この場合、キーに関連付けられた関数が見つからない理由がわかりません"speak"
。これを修正しようとして、inにB
関連付けられた値を返す関数アプローチをスニペットに実装することにしましたが、うまくいきました。確かに と (から適応)は同じ効果があります。key
B
__index = A
B
__index = function(t,key) return A[key] end
明確化をいただければ幸いです。