この初版は、Lua 5.0 のために書かれました。以後のバージョンでも大部分は関連性がありますが、いくつかの違いがあります。
第 4 版は Lua 5.3 を対象にしており、Amazon や他の書店で入手可能です。
この本を購入することも、Lua プロジェクトをサポートすることに役立ちます。
![]() |
Lua でのプログラミングLua | ![]() |
| 第 2 部 テーブルとオブジェクト 第 13 章 メタテーブルとメタメソッド |
__index と __newindex の両方は、インデックスがテーブルにない場合にのみ関連します。テーブルへのすべてのアクセスを取得する唯一の方法は、テーブルを空のままにしておくことです。したがって、テーブルへのすべてのアクセスを監視したい場合は、実際のテーブルのプロキシを作成する必要があります。このプロキシは、すべてのアクセスを追跡し、元のテーブルにリダイレクトする適切な __index と __newindex メタメソッドを持つ空のテーブルです。t が追跡したい元のテーブルであるとします。次のように記述できます。
t = {} -- original table (created somewhere)
-- keep a private access to original table
local _t = t
-- create proxy
t = {}
-- create metatable
local mt = {
__index = function (t,k)
print("*access to element " .. tostring(k))
return _t[k] -- access the original table
end,
__newindex = function (t,k,v)
print("*update of element " .. tostring(k) ..
" to " .. tostring(v))
_t[k] = v -- update original table
end
}
setmetatable(t, mt)
このコードは t へのあらゆるアクセスを追跡します > t[2] = 'hello'
*update of element 2 to hello
> print(t[2])
*access to element 2
hello
(残念ながら、このスキームではテーブルをトラバースできないことに注意してください。pairs 関数は元のテーブルではなく、プロキシに対して動作します。)複数のテーブルを監視する場合、それぞれに異なるメタテーブルは必要ありません。代わりに、なんらかの方法で各プロキシを元のテーブルに関連付け、すべてのプロキシに共通のメタテーブルを共有できます。プロキシをテーブルに関連付ける簡単な方法は、他の手段にこのフィールドが使用されないように自信があれば、元のテーブルをプロキシのフィールドに保持することです。これを保証する簡単な方法は、誰もアクセスできない秘密鍵を作成することです。これらのアイデアをまとめると、次のコードになります
-- create private index
local index = {}
-- create metatable
local mt = {
__index = function (t,k)
print("*access to element " .. tostring(k))
return t[index][k] -- access the original table
end,
__newindex = function (t,k,v)
print("*update of element " .. tostring(k) ..
" to " .. tostring(v))
t[index][k] = v -- update original table
end
}
function track (t)
local proxy = {}
proxy[index] = t
setmetatable(proxy, mt)
return proxy
end
これで、テーブル t を監視したい場合は、t = track(t) とするだけで済みます。| 著作権 © 2003–2004 Roberto Ierusalimschy. All rights reserved. | ![]() |