LUA教程表相关的Metamethods 监控表 -57

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函数将对proxy进行操作,而不是原始的表。)
如果我们想监控多张表,我们不需要为每一张表都建立一个不同的metatable。我们只要将每一个proxy和他原始的表关联,所有的proxy共享一个公用的metatable即可。将表和对应的proxy关联的一个简单的方法是将原始的表作为proxy的域,只要我们保证这个域不用作其他用途。一个简单的保证它不被作他用的方法是创建一个私有的没有他人可以访问的key。将上面的思想汇总,最终的结果如下:

-- 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)。


发布日期:

所属分类: 编程 标签:


没有相关文章!