lua-users home
lua-l archive

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


On Sat, Nov 30, 2013 at 9:35 AM, Georgios Petsagourakis
<petsagouris+lual@gmail.com> wrote:
> In both of these cases it is difficult to understand how to make this
> functionality happen in Lua 5.2 though with setfenv and getfenv missing.

Without rewriting the code that you posted:

The part that you showed that isn't directly included in 5.2 is the
ability to extract a function's environment after it's been passed in.
To accomplish the same outcome in 5.2, some good old refactoring needs
to take place. Presumably (or I could look it up and verify it) this
was because doing so breaks some basic rules that should be more
difficult to break (debug library) or done explicitly, by changing the
way that `func` is implemented.

Some refactoring strategies:

Rewrite the function so that you can pass in an environment. I haven't
done much of this but func's arguments would start with _ENV

local func(_ENV, ...)
 ---code that does stuff, using the provided _ENV
end

---if you wanted to keep the current env as a shadow:

local func(env, ...)
    _ENV = setmetatable(env, {__index = _ENV}) --or the other way around
   ---code that does stuff
end

----------

I'm not sure if my answer is too basic or not. Nobody answered right
away, so I thought I'd start here. Let me know if I'm off...

-Andrew


_ENV is the first upvalue of every scope and points to the previ to
the previous scope's _ENV, which at the very top-most level is _G. You
probably know this, but it bares stating because that's all it is.

Therefore, to stash a current environment `local env = _ENV` and to
default to an old _ENV `setmetatable(_ENV, {__index = env})` and to do
anything fancier, assign `__index` to a function that does stuff, as
your function did.