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
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
```lua
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
issue description + repro
going through documentation tasks, i realized that i expect
tab.readonly
to create a proxy which also inherits othertab
functionality, eg.tab.print
.repro script
since
tab.print
callspairs
, running the above results in aC stack overflow
pointing to https://github.com/monome/norns/blob/15c9cf9304d500b28c7ad04d6ddf4f85a4a6d095/lua/lib/tabutil.lua#L231workaround
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 reflectsexpose
+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
```lua 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