I have problem with Lua modules.
Let’s say there is a module Data.lua:
local M = {};
M.grid = {};
return M;
Also there are two scripts Player.script and GameController.script.
They both require the module like this:
local data = require "modules.Data"
The problem is that both scripts see different data.grid variable. It looks like every time a script requires a module it gets an instance of that module.
I also tried to print(data.grid) in order to get its address: Player.script:table: 0x0bfe7800 GameController.script:table: 0x0a3de490
I expected that described module to behave as a singleton.
What I am doing wrong?
I tried to recreate your case, and curiously I don’t see the same result. For me each require’d module is the same, as expected.
This is my test:
mod.lua:
local M = {}
M.test_val = 1
M.alter = function ()
M.test_val = M.test_val + 1
end
M.read = function ()
return M.test_val
end
return M
a.script:
local mod = require("test.mod")
function init(self)
print("a")
print(mod)
mod.alter()
print(mod.read())
end
b.script:
local mod = require("test.mod")
function init(self)
print("b")
print(mod)
mod.alter()
print(mod.read())
end
Output:
DEBUG:SCRIPT: a
DEBUG:SCRIPT: table: 0x0e4013d0
DEBUG:SCRIPT: 2
DEBUG:SCRIPT: b
DEBUG:SCRIPT: table: 0x0e4013d0
DEBUG:SCRIPT: 3
However, if you would uncheck script > shared_state in game.project, and require from different script types (e.g. one .script and one .gui_script), the modules would be different. But clearly you are not doing that.
Could you try my code and see which result you get?
The problem is that I misspelled the module name in this way:
a.script: mod = require "test.mod"
b.script: mod = require "test.Mod"
The only difference here is capital and small “M”. Actually you can also write something like mOd or MOD, etc. Looks like each combination of capital and small letters (while name spelled correctly) “creates” a new instance.
It doesn’t throw any errors, it just creates a new instance of module with default values (we can put print(M) before return M in module code and see that the table was created two times with different addresses).
Is it a bug or situation which should be kept in mind?
Interesting. It’s not really a bug, but I’d say it’s something that should be prevented or warned about either on an engine level or Lua level. It’s possible to prevent or warn about it from Lua by replacing the require function or by creating a custom loader (package.loaders) that would do a case insensitive check the of the package.loaded table for an already existing module instance and return that.