lua-users home
lua-l archive

Re: getfenv question

[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.

AltStyle によって変換されたページ (->オリジナル) /