lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


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.