Search code examples
luaclosureslua-apilua-5.2

Lua create multiple closure instances


I have some lua code in a file. I want to create multiple closure instances of this code, each with a different _ENV upvalue. I can use luaL_loadfile to load the file and set the first upvalue, N times with different tables, to create N instances. But wouldn't this load and compile the file N times?

The lua equivalent of what i want to do is the following, except without the loadfile

func_list = {}

for i = 1, 10 do
    local new_env = {hello=i, print=print}
    func_list[i] = loadfile("Code.lua", "t", new_env)
end

for i = 1, 10 do
    func_list[i]()
end

------ Code.lua ------
print(hello*hello)

is there a better way to do this?


Solution

  • Whenever you load a string/file in Lua, what you get in return is a function to call to actually run the file. What load does for you is just some additional processing to set the _ENV.

    However, nothing prevents you from setting _ENV yourself. You could do it with something like this:

    -- Code.lua --
    _ENV = ...
    print(hello * hello)
    

    Then, you could load/compile the file just once, and use multiple instances as such:

    local code = loadfile("Code.lua")
    
    env_list = {}
    for i = 1, 10 do
        local new_env = {hello=i, print=print}
        code(new_env)
        env_list[i] = new_env
    end
    

    If you do not want the user to write _ENV = ... in every file, you could instead load the file into a string, prepend the line yourself and use load to compile the source. But this would not work on compiled files.