It is my understanding that in Lua 5.2 that environments are stored in upvalues named `_ENV`. This has made it really confusing for me to modify the environment of a chunk before running it, but after loading it.

I would like to load a file with some functions and use the chunk to inject those functions into various environments. Example:

```
chunk = loadfile( "file" )

-- Inject chunk's definitions
chunk._ENV = someTable -- imaginary syntax
chunk( )

chunk._ENV = someOtherTable
chunk( )

```

Is this possible from within Lua? The only examples I can find of modifying this upvalue are [with the C api](https://stackoverflow.com/questions/19167986/how-do-i-set-via-the-lua-c-api-the-environment-table-for-a-chunk-of-lua-code-p) (another [example from C api](http://lua.2524044.n2.nabble.com/Change-value-of-upvalue-from-within-function-td7642150.html)), but I am trying to do this from within Lua. Is this possible?

Edit: I'm unsure of accepting answers using the debug library. The [docs state](http://www.lua.org/manual/5.2/manual.html#6.10) that the functions may be slow. I'm doing this for efficiency so that entire chunks don't have to be parsed from strings (or a file, even worse) just to inject variable definitions into various environments.

Edit: Looks like this is impossible: [Recreating setfenv() in Lua 5.2](https://stackoverflow.com/questions/14290527/recreating-setfenv-in-lua-5-2?rq=1)

Edit: I suppose the best way for me to do this is to bind a C function that can modify the environment. Though this is a much more annoying way of going about it.

Edit: I believe a more natural way to do this would be to load all chunks into separate environments. These can be "inherited" by any other environment by setting a metatable that refers to a global copy of a chunk. This does not require any upvalue modification post-load, but still allows for multiple environments with those function definitions.
['https://Stackoverflow.com/questions/20735570', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/1825760/']
The simplest way to allow a chunk to be run in different environments is to make this explicit and have it receive an environment. Adding this line at the top of the chunk achieves this:

`_ENV=...`

Now you can call `chunk(env1)` and later `chunk(env2)` at your pleasure.

There, no `debug` magic with upvalues.

Although it will be clear if your chunk contains that line, you can add it at load time, by writing a suitable reader function that first sends that line and then the contents of the file.
If you don't want to modify your chunk (per LHF's great answer) here are two alternatives:

### Set up a blank environment, then dynamically change its environment to yours

```lua
function compile(code)
   local meta = {}
   local env = setmetatable({},meta)
   return {meta=meta, f=load('return '..code, nil, nil, env)}
end

function eval(block, scope)
   block.meta.__index=scope
   return block.f()
end

local block = compile('a + b * c')
print(eval(block, {a=1, b=2, c=3})) --> 7
print(eval(block, {a=2, b=3, c=4})) --> 14

```

### Set up a blank environment, and re-set its values with your own each time

```lua
function compile(code)
   local env = {}
   return {env=env, f=load('return '..code, nil, nil, env)}
end

function eval(block, scope)
   for k,_ in pairs(block.env) do block.env[k]=nil end
   for k,v in pairs(scope) do block.env[k]=v end
   return block.f()
end

local block = compile('a + b * c')
print(eval(block, {a=1, b=2, c=3})) --> 7
print(eval(block, {a=2, b=3, c=4})) --> 14

```

Note that if micro-optimizations matter, the first option is about 2✕ as slow as the `_ENV=...` answer, while the second options is about 8–9✕ as slow.