Search code examples
lualua-tableluajit

Write-once table in lua?


I'd like to have a write-once table in Lua (specifically LuaJIT 2.0.3), so that:

local tbl = write_once_tbl()
tbl["a"] = 'foo'
tbl["b"] = 'bar'
tbl["a"] = 'baz'  -- asserts false

Ideally, this would otherwise function like a regular table (pairs() and ipairs() work).

__newindex is basically the opposite of what I'd want for implementing this easily, and I am unaware of any techniques for making a proxy table pattern work with pairs() and ipairs().


Solution

  • You need to use a proxy table, that is, an empty table that catches all access to the actual table:

    function write_once_tbl()
        local T={}
        return setmetatable({},{
            __index=T,
            __newindex=
                function (t,k,v)
                    if T[k]==nil then
                        T[k]=v
                    else
                        error("table is write-once")
                    end
                end,
            __pairs=  function (t) return  pairs(T) end,
            __ipairs= function (t) return ipairs(T) end,
            })
    end
    

    Note that __pairs and __ipairs only work from Lua 5.2 onwards.