原始表访问

有时候,你不想触发元方法,而是真正地写入或读取给定的密钥,而没有一些巧妙的功能包裹在访问中。为此,lua 为你提供原始表访问方法:

-- first, set up a metatable that allows no read/write access
local meta = {
    __index = function(object, index)
        -- raise an error
        error(string.format("the key '%s' is not present in object '%s'", index, object))
    end,
    __newindex = function(object, index, value)
        -- raise an error, this prevents any write access to the table
        error(string.format("you are not allowed to write the object '%s'", object))
    end
}

local t = { foo = "bar" }
setmetatable(t, meta)

-- both lines raise an error:
--print(t[1])
--t[1] = 42

-- we can now circumvent this problem by using raw access:
print(rawget(t, 1)) -- prints nil
rawset(t, 1, 42) -- ok

-- since the key 1 is now valid, we can use it in a normal manner:
print(t[1])

有了这个,我们现在可以重写以前的 __newindex 方法来实际将值写入表中:

meta.__newindex = function(object, index, value)
    print(string.format("writing the value '%s' to the object '%s' at the key '%s'",
                         value, object, index))
    rawset(object, index, value)
end