lua-users home
lua-l archive

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


Mark Hamburg preguntó:

> Is there a way other than wrapping things in pcall to tell what the 
maximum
> level I can pass to getfenv is?

> I'm trying to implement pseudo-dynamic scoping by searching up the call
> chain for the first function environment referencing a particular 
variable.

This seems like a very slow way of implementing dynamic scoping. Why don't
you do something like this:

do
  local dynvars = {}
  setmetatable(getfenv(), {
    __index = dynvars,
    __newindex = function(t, k, v)
        if dynvars[k] ~= nil then
          dynvars[k] = v
         else
          rawset(t, k, v)
        end
      end
  }

  local function propagate(dv, val, okflag, ...)
    dynvars[dv] = val
    if okflag then return unpack(arg)
              else error(args[1])
    end
  end

  function with(dv, val, fn, ...)
    local old
    old, dynvars[dv] = dynvars[dv], val
    return propagate(dv, old, pcall(fn, unpack(arg))}
  end
 
end

The syntax for with is going to be a bit of a pain, but you could
macro process:
  with var = val do ... end
into
  with("var", val, function() ... )

And, actually, if you were only going to use that syntax,
you could simplify the definition of with :

function with(dv, val, fn)
  local old
  old, dynvars[dv] = dynvars[dv], val
  local okflag, err = pcall(fn)
  dynvars[dv] = old
  if not okflag then error(err) end
end

It actually would not be that hard to implement that in the
Lua parser.