junius
junius

Reputation: 570

Execute Loaded Lua files in a certain scope

I'm using Lua as a configuration format for a project mine. Let's suppose I have the following contrived example, we'll call conf.lua:

title = "Lorem Ipsum"
author = "John Doe"
date = "01 January 2000"

Now, trivially, I can of course load this file like so:

dofile("conf.lua")

However, the problem with this is that these definitions are set in the global namespace, which I do not want. Furthermore, it makes it difficult to access the different variables as a whole (e.g loop over the set of configuration variables). One solution would be to rewrite conf.lua like so:

local conf = {
    title = "Lorem Ipsum",
    author = "John Doe",
    date = "01 January 2000"
}

return conf

and in turn, load conf.lua with the following code:

local configuration = dofile("conf.lua")

However, this is non-ideal for I think obvious reasons. It requires my users to keep track of commas, to have to write local, to have to remember to return the table at the end. What would be nice is if there were some way to cause conf.lua to execute with a custom scope of some sort.

Upvotes: 2

Views: 1566

Answers (1)

Oka
Oka

Reputation: 26355

Instead of using dofile, simply use loadfile.

loadfile allows you to specify the environment the loaded chunk will be executed in. Setting this as an empty table allows upvalues to be placed in that table.

local function load_conf ()
    local env = {}

    local chunk, err = loadfile('conf.lua', 'bt', env)

    if not err then
        chunk()
    end

    return env, err
end

local conf, conf_err = load_conf()

print(conf_err)
print(conf.title, conf.author, conf.date)

loadfile uses similar rules as load, except that it loads a chunk from a file, or stdin, instead of from a string or string building function.


Note that setfenv is required for backwards compatibility with Lua 5.1. You'd use the following (or something like it) before executing your loaded chunk.

if setfenv then
    setfenv(chunk, env)
end

See §8.1 – Changes in the Language of the Lua 5.2 Reference Manual.


Finally, consider running your chunks in protected mode, using pcall, so that a config file doesn't crash your main program.

Upvotes: 6

Related Questions