Reputation: 570
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
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