tab.readonly doesn't endow pairs/ipairs for proxy
Opened this issue · 0 comments
issue description + repro
going through documentation tasks, i realized that i expect tab.readonly
to create a proxy which also inherits other tab
functionality, eg. tab.print
.
repro script
function init()
mana = {
white = {"order", "peace", "light"},
blue = {"intellect", "logic", "manipulation"},
black = {"power", "death", "corruption"},
red = {"freedom", "chaos", "fury"},
green = {"life", "nature", "evolution"}
}
mana_green_editable = tab.readonly{
table = mana, -- which table to copy
except = {'green'}, -- which keys should remain writeable
}
tab.print(mana_green_editable)
end
since tab.print
calls pairs
, running the above results in a C stack overflow
pointing to
Line 231 in 15c9cf9
workaround
i'm v dumb about metatable stuff, but i'm able to resolve the stack overflow issue by building and adjusting a local tpairs
table which reflects expose
+ except
params. see https://www.diffchecker.com/fNViUcZr/ for side-by-side to current code (chose a different name just for differentiation in testing):
pairs workaround
function treadonly(params)
local t = params.table
local exceptions = params.except or {}
local proxy = {}
local tpairs = {}
for k,v in pairs(t) do
if params.expose == nil or tab.contains(params.expose, k) then
tpairs[k] = v
end
end
local mt = {
__index = function(_, k)
if params.expose == nil or tab.contains(params.expose, k) then
tpairs[k] = t[k]
return t[k]
end
return nil
end,
__newindex = function (_,k,v)
if (tab.contains(exceptions, k)) then
t[k] = v
tpairs[k] = v
else
error("'"..k.."', a read-only key, cannot be re-assigned.")
end
end,
__pairs = function (_) return pairs(tpairs) end,
__ipairs = function (_) return ipairs(tpairs) end,
}
setmetatable(proxy, mt)
return proxy
end
if this is at all reasonable, i'd be happy to PR this fix -- or i'd be happy to PR a much better one with some quick guidance <3