第一版是為 Lua 5.0 編寫的。雖然在很大程度上仍然適用於後續版本,但仍有一些差異。
第四版針對 Lua 5.3,可在 Amazon 和其他書店購買。
購買本書,您也可以協助 支援 Lua 專案。
![]() |
用 Lua 程式設計 | ![]() |
第二部分。表格和物件 第 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。保留所有權利。 | ![]() |