How can I load a file of lua tables and variables without polluting the global environment? Since doing a loadfile and running it just loads everything in the global space and may overwrite something else which I don't want.
Loadfile without polluting global environment
6.5k views Asked by Milind At
3
There are 3 answers
0
On
Here is a dofile() version of RBerteig's answer where you supply the environment and the result, if any, is returned (I tried to do this as a comment, but couldn't figure out to format it):
local function DofileIntoEnv(filename, env)
setmetatable ( env, { __index = _G } )
local status, result = assert(pcall(setfenv(assert(loadfile(filename)), env)))
setmetatable(env, nil)
return result
end
I wanted to be able to load multiple files into the same environment, and some of these files had a 'return something' in them. Thanks RBerteig, your answer was helpful and instructive!
In Lua 5.1 and without much error handling you could do this:
The first line creates an empty environment table that can see all existing globals, but which cannot trivially change them since they are visible only by proxy through the
__index
metamethod. Any globals the script creates would be stored inenv
, which is returned. This will work well for simple scripts that just set a bunch of configuration parameters, and which might need to call simple safe functions to set them based on conditions at run time.Note that making the globals visible to the script is a convenience. Although the globals cannot be modified from the script in the obvious way,
_G
is a global variable that contains a reference to the global environment (containing_G._G
,_G._G._G
, etc...) and_G
can be modified from the script which could lead to further issues.So rather than using
_G
for the index, it would be much better to construct a table that contains only functions known to be safe and known to be needed by your script's author.A complete solution would be to run the script in a sandbox, and possibly further protected to prevent accidental (or deliberate) denial of service or worse. Sandboxes are covered in more detail at the Lua User's Wiki. The topic is deeper than it seems at first glance, but as long as your users are trusted to be non-malicious then practical solutions are straightforward.
Lua 5.2 changes things a little bit by eliminating
setfenv()
in favor of a new parameter toload()
. Details are also in the wiki page.