lua-users home
lua-l archive

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


On Tuesday, April 09, 2013 11:06:08 AM steve donovan wrote:
> It might not be the first upvalue, depends whether a 'global' is referenced
> first before any other upvalues.
> 
> That's fine, always thought that function environments were _hard to
> explain_. (great way to evaluate a feature)

I've sometimes wished that _ENV, if it is used in a function, will always be 
the first upvalue. But it's a minor issue that's easily overlooked.

Thus this bit of magic.

    local debug = require "debug"
    local function fgetindex(func, name)
      local info = debug.getinfo(func, 'u')
      if not info then error("not a function") end
      for up = 1,info.nups do
        local upname,upval = debug.getupvalue(func, up)
        if upname == name then
          return upval
        end
      end
      return nil
    end
    local function fsetindex(func, name, value)
      local info = debug.getinfo(func, 'u')
      if not info then error("not a function") end
      for up = 1,info.nups do
        local upname = debug.getupvalue(func, up)
        if upname == name then
          debug.setupvalue(func, up, value)
          return
        end
      end
    end
    debug.setmetatable(functionindex, {
      __index=fgetindex,
       __newindex=fsetindex})

    -- somefunction._ENV = {}

If you need to access function upvalues frequently, the lookup can be improved 
with a weak table.

-- 
tom <telliamed@whoopdedo.org>