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

__index和__newindex都是只有当表中访问的域不存在时候才起作用。捕获对一个表的所有访问情况的唯一方法就是保持表为空。因此,如果我们想监控一个表的所有访问情况,我们应该为真实的表创建一个代理。这个代理是一个空表,并且带有__index和__newindex metamethods,由这两个方法负责跟踪表的所有访问情况并将其指向原始的表。假定,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函数将对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)。

原文:LUA一个小巧脚本语言学习笔记

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

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

511遇见

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值