[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Metamethod registry
- From: "Soni L." <fakedme@...>
- Date: Tue, 6 Sep 2016 14:31:58 -0300
The standard Lua metamethods/metafields can all be invoked as needed:
__index - x[k]
__newindex - x[k] = v
__lt - x < y
__le - x <= y
__eq - x == y
(... and so on ...)
__tostring - tostring(x)
__pairs - pairs(x)
__metatable - getmetatable(x) -- kinda
(__gc doesn't count because it's a security exploit)
But user-defined metamethods are a bit tricky. There are all sorts of
things to consider:
- Sandboxes
- __metatable
- etc
So as a way to get them painlessly, can we get a metamethod registry? E.g.
do
local mymeta = registermeta("__tonumber") -- custom metamethod
local function mytonumber(x)
local f = mymeta.get(x)
return (f(x))
end
local ok, err = pcall(registermeta, "__index") -- standard lua
metamethods don't work
assert(not ok)
local ok, err = pcall(registermeta, "__tonumber") -- cannot register
someone else's metamethod
assert(not ok)
local t = setmetatable({}, {__tonumber=function(x) return 0 end,
__metatable=false})
assert(not getmetatable(t))
assert(mytonumber(t) == 0)
mymeta.close() -- should we have a close() method like this? not sure
about this one...
mymeta = nil
end
collectgarbage()
collectgarbage()
assert(registermeta("__tonumber")) -- if the handle was gced, then we
can register it again
I'm pretty sure you can't do this with standard
setmetatable/getmetatable, so a clean, safe wrapper around
debug.getmetatable that doesn't "leak" would be nice, especially so for
sandboxes and stuff.
--
Disclaimer: these emails may be made public at any given time, with or without reason. If you don't agree with this, DO NOT REPLY.