I am learning from \"Programing in Lua\" by Roberto Ierusalimschy, and I found that in the book, the example of Sandboxing uses the function setfenv()
to change
When you assign to _ENV
from within sandbox
, you're not overwriting the global environment--you're replacing the _ENV
upvalue of the currently running code. Adding calls to print(_ENV)
may help you better understand the identities of the tables involved.
For example:
function print_env()
print(_ENV)
end
function sandbox()
print(_ENV) -- prints: "table: 0x100100610"
-- need to keep access to a few globals:
_ENV = { print = print, print_env = print_env, debug = debug, load = load }
print(_ENV) -- prints: "table: 0x100105140"
print_env() -- prints: "table: 0x100105140"
local code1 = load('print(_ENV)')
code1() -- prints: "table: 0x100100610"
debug.setupvalue(code1, 1, _ENV) -- set our modified env
code1() -- prints: "table: 0x100105140"
local code2 = load('print(_ENV)', nil, nil, _ENV) -- pass 'env' arg
code2() -- prints: "table: 0x100105140"
end
The loadin
function was present in some pre-release versions of Lua 5.2 but was removed before the final release. Instead, the Lua 5.2 load and loadfile functions take an env
argument. You can also modify the _ENV
of another function using debug.setupvalue.