Is there a way to call require in a Lua file, and have the module set the environment of the file that calls it? For example, if I have a DSL (domain specific language) that defines the functions Root and Sequence defined in a table, can I have something like setfenv(1, dslEnv) in the module that allows me to access those functions like global variables?
The goal I in mind is using this is a behavior tree DSL in a way that makes my definition file look like this (or as close it as possible):
require "behaviortrees"
return Root {
Sequence {
Leaf "leafname",
Leaf "leafname"
}
}
without having to specifically bring Root, Sequence, and Leaf into scope explicitly or having to qualify names like behaviortrees.Sequence.
In short, I'm trying to make the definition file as clean as possible, without any extraneous lines cluttering the tree definition.
Can I have something like
setfenv(1, dslEnv)in the module that allows me to access those functions like global variables?Sure you can. You just have to figure out the correct stack level to use instead of the
1in yoursetfenvcall. Usually you'd walk up the stack using a loop withdebug.getinfocalls until you find therequirefunction on the stack, and then you move some more until you find the next main chunk (just in case someone callsrequirein a function). This is the stack level you'd have to use withsetfenv. But may I suggest a ...Different Approach
requirein Lua is pluggable. You can add a function (called a searcher) to thepackage.loadersarray, andrequirewill call it when it tries to load a module. Let's suppose all your DSL files have a.btsuffix instead of the usual.lua. You'd then use a reimplementation of the normal Lua searcher with the differences that you'd look for.btfiles instead of.luafiles, and that you'd callsetfenvon the functionreturned byloadfile. Something like this:If you put this in a module and
requireit once from your main program, you can thenrequireyour DSL files with the custom environment from.btfiles somewhere where you would put your.luafiles as well. And you don't even need therequire("behaviortrees")in your DSL files. E.g.:File
xxx.bt:File
main.lua: