この初版は、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. | ![]() |