LUA设计思路(2)安全的table

本文介绍如何使用Lua的元表来阻止非法变量的左值引用,通过设置metatable的__newindex属性,可以有效地控制table中变量的动态增加,防止因拼写错误导致的难以发现的问题。

对于一个table而言,如果右值引用一个不存在的变量,会引发nil错误,但如果左值引用一个不存在的变量则仅会创建一个变量。这是一种非常危险的行为,会导致拼写错误无法被检测出来。
解决的办法是:当确认table不应该动态增加变量时(table动态增加变量应该受到应有的限制)就是用元表(metatable)对左值访问进行限制:
t = {}
setmetatable(t,{ __newindex = function( t,k,v )
    print(debug.traceback())
    assert(false, "Invalid key "..k.." has been left-refrenced.")
end })
上述为实现原理,如果table不是由工厂创建的,那么将会很难控制其访问。对于一个工厂创建的表,则可以在最后返回创建元素前将__newindex锁定从而实现控制访问。
NewIndexError = function( k )
    print( debug.traceback() )
    assert( false, "Invalid key "..k.." has been left-refrenced." )
end
AppleFactory = {}

AppleFactory.OnEat = function( self, ... ) end

AppleFactory.New = function()
    local apple = {}
    apple.Color = "red"
    apple.OnEat = AppleFactory.OnEat
    --......
    getmetatable(apple).__newindex = function(t,k,v)
        -- 先处理继承等等
        if ...
        else
            -- 如果需要的特殊处理都没有进行,可以认为是一个拼写错误或非法添加变量
            NewIndexError( k )
        end
    end
end
在这里引出一个比较核心的思想:由工厂管理表。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值