Reputation: 2597
So I have a Lua script in which I set the environment of a function and define other functions that I make available in the environment. The issue is that when I call the function I did setfenv
on, any function it calls within the environment uses the global _G
environment to lookup values as opposed to the environment I set when calling the initial function. I have replicated the issue below:
> function f() print(t) end
> t = 5
> f()
5
> env = {}
> env['print'] = print
> env['t'] = 7
> env['f'] = f
> setfenv(f, env)
> f()
7
> setfenv(f, _G)
> f()
5
> function g() f() end
> g()
5
> setfenv(g, env)
> g()
5
Is there a way to get the environment to propagate to all calls without having to do setfenv
on every function I want to add to env
(basically, so that the last call in the example to g()
would return 7
instead of 5
)?
Using Lua 5.1.
Upvotes: 3
Views: 2095
Reputation: 23747
You can write a function so that it automatically changes its own environment on every call
-- This code works on Lua 5.1, 5.2, 5.3
local getfenv = getfenv or function() end
local setfenv = setfenv or getfenv
a = 1
function f(env)
local _ENV = env or getfenv(2) or _ENV; setfenv(1, _ENV)
print(a)
end
env = { a = 2, print = print }
-- inherit environment for this call
f() --> 1
-- set special environment for this call
f(env) --> 2
f() --> 1
Or simply setfenv(1, getfenv(2))
if you are working only with Lua 5.1 and want to ALWAYS inherit environment.
Upvotes: 1