Page 1 of 1

Require and subdirectories

Posted: Sun Feb 21, 2021 2:55 pm
by dementedpeanut
Consider this folder structure

Code: Select all

control.lua
scripts/
	some_module.lua
	file1.lua
control.lua imports the module like so

Code: Select all

local module = require("scripts.some_module")
and file1.lua imports like

Code: Select all

local module = require("some_module")
The issue I am having is that both of these imports reference NEW instances of that module, I am guessing because require uses the string parameter as a key for whether or not it has been loaded.

I am relatively new to lua so not sure on best practices here and how to solve this issue?

Re: Require and subdirectories

Posted: Sun Feb 21, 2021 3:44 pm
by Pi-C
dementedpeanut wrote:
Sun Feb 21, 2021 2:55 pm
Consider this folder structure

Code: Select all

control.lua
scripts/
	some_module.lua
	file1.lua
The issue I am having is that both of these imports reference NEW instances of that module, I am guessing because require uses the string parameter as a key for whether or not it has been loaded.
Put functions or data into some_module.lua. You can access these functions/data from both control.lua and file1.lua. That's probably enough if you want to do some simple stuff, like converting a position:

Code: Select all

--some_module.lua:
some_functions = {}

some_functions.get_x = function(position)
 return position and position.x or position[1]
end

return some_functions

--control.lua:
local my_functions = require("scripts.some_functions")

local x = my_functions.get_x({123, 456}) 
However, as you've already noticed, control.lua and file1.lua use different instances of some_functions.lua, so you can't use that to share data across files. For this, you'll need the table "global" (which is global to your mod only, and isolated from other mods, and will be saved with the game).

Code: Select all

--control.lua:
local my_functions = require("scripts.some_functions")

global = global or {}
global.x = my_functions.get_x({123, 456}) 

--file1.lua
local my_functions = require("scripts.some_functions")

global = global or {}
local x = global.x or my_functions.get_x({234, 567})
Hope that helps a bit! :-)

Re: Require and subdirectories

Posted: Sun Feb 21, 2021 5:49 pm
by dementedpeanut
Thanks! More out of curiosity than anything but is there a way to get it to load only once? If I have another file in the same directory as file1.lua it would not create another instance of some_module.lua and instead return the same value.

Re: Require and subdirectories

Posted: Sun Feb 21, 2021 6:11 pm
by DaveMcW
Don't use the local keyword if you want a global module.

control.lua:

Code: Select all

my_functions = require("scripts.some_functions")
require("scripts.file1")
file1.lua:

Code: Select all

assert(my_functions, "my_functions does not exist!") -- will not fail

Re: Require and subdirectories

Posted: Sun Feb 21, 2021 6:45 pm
by eradicator
dementedpeanut wrote:
Sun Feb 21, 2021 5:49 pm
Thanks! More out of curiosity than anything but is there a way to get it to load only once?
As you've noticed yourself loaded modules are indexed by string key (and references stored in the table _ENV.packages.loaded). Thus the easiest way to load the same thing into different local environments is to use identical string keys - i.e. absolute paths - in both files.

Code: Select all

local mymod = require '__my-mod-name__/subdirectory/mymod.lua'
If you need something more elaborate you could write a wrapper function around require() that translates relative paths to absolute or manually scans packages.loaded.