Таблица с однократной записью в lua?

Я хотел бы иметь таблицу однократной записи в Lua (в частности, LuaJIT 2.0.3), чтобы:

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

В идеале это могло бы функционировать как обычная таблица (работают функции pairs() и ipairs()).

__newindex в основном противоположен тому, что я хотел бы легко реализовать, и я не знаю каких-либо методов, позволяющих заставить шаблон прокси-таблицы работать с парами () и ipairs ().


person MikeMx7f    schedule 03.11.2017    source источник


Ответы (1)


Вам нужно использовать прокси-таблицу, то есть пустую таблицу, которая перехватывает все обращения к фактической таблице:

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

Обратите внимание, что __pairs и __ipairs работают только с Lua 5.2 и выше.

person lhf    schedule 03.11.2017
comment
Я знаю прокси-таблицы, но они не работают с парами() или ipairs(). Я только что попробовал ваш фрагмент кода и убедился, что пары () и ipairs () не работают с ним. - person MikeMx7f; 14.11.2017
comment
@MikeMx7f, они есть в Lua 5.2 и 5.3. - person lhf; 14.11.2017
comment
Я протестировал ваш фрагмент кода здесь: lua.org/cgi-bin/demo, который используя Луа 5.3. - person MikeMx7f; 15.11.2017
comment
@MikeMx7f, вам нужно установить метаметоды __pairs и __ipairs. - person lhf; 15.11.2017
comment
Спасибо. Можете ли вы отредактировать это в ответе, чтобы я мог его принять (поскольку в вопросе указано, что пары () и ipairs () работают)? Ваше здоровье. - person MikeMx7f; 15.11.2017