Hey all,
I’m currently working on an in-game Roblox application system – and I need some help!
I want to achieve the ability for 2 modules to require each other – while not causing an error… which may be an impossible thing, but I’m also wondering if there’s a potential replacement I could use?
The issue is… well… Requested module was required recursively.
I’ve tried using values inside of the pertaining scripts but the tables are exhausting to recreate and I need them to communicate in a particular way.
I searched for answers on the Developer Hub yet I didn’t find much help
If you’d like my code, I can send it, but the coding doesn’t appear to be the issue.
On a side note, sorry if I made a mistake – this is my first post.
I thought I answered to a similar question earlier:
To avoid require recursions, map out the requires and make sure it does not create a cycle within it. For instance, the easiest recursion that can be found is when A requires B and B requires A. Otherwise you have A to B to C to A recursion.
This is a band-aid solution to a structural problem in your code that I personally am very guilty of abusing, but if module A requires module B, but module B also needs to require module A in some sections,like a function, then requiring module A only inside the scope of those functions instead of the base scope of the module script will avoid recursively requiring.
--Modulescript A
local moduleA = {}
local moduleB = require("SomePathToModuleB")
--... the rest of module A
return moduleA
--Modulescript B
local moduleB = {}
moduleB.someFunctionThatNeedsA = function()
local moduleA = require("SomePathToModuleA")
--..the rest of the function
end
--... the rest of module B
return moduleB
I think the code will still cause a recursive requiring even if it was in a function environment later. After it enters the function environment, module A is required and that code is executed and B is required again. B is executed again and enters function environment which in return goes back to A again.
Nope, speaking from experience it compiles just fine and works at runtime just fine too. Like I said, definitely a structural problem since even if it works fine it’s still technically a circular dependency, it just doesn’t result in a recursive require.
I threw a small example to demonstrate. Throw these scripts into an empty baseplate example and you’ll see it runs just fine:
ModuleA:
local moduleA = {}
local moduleB = require(game:GetService("ReplicatedStorage").ModuleB)
moduleA.doThing = function()
print("thing done")
end
moduleA.doThingWithB = function()
moduleB:doThingFromAWithB();
print("thing done")
end
moduleA.doThingWithBThatRequiresA = function()
moduleB:doThingWithA();
print("thing done")
end
return moduleA
ModuleB:
local moduleB = {}
moduleB.doThingWithA = function()
local moduleA = require(game:GetService("ReplicatedStorage").ModuleA)
moduleA:doThing();
end
moduleB.doThingWithoutA = function()
print("b doing thing without A")
end
moduleB.doThingFromAWithB = function()
print("b doing thing from A")
end
return moduleB
Local script:
local modA = require(game:GetService("ReplicatedStorage").ModuleA)
local modB = require(game:GetService("ReplicatedStorage").ModuleB)
modA:doThing();
modA:doThingWithB();
modB:doThingWithoutA();
modB:doThingWithA();
modA:doThingWithBThatRequiresA();
I don’t really know enough about Lua to explain ~why~ this works, but if I had to assume I’m guessing when each module script is initialized, the scope of these functions aren’t actually entered until they’re called at runtime, which means ModuleB is able to return the module itself before it has to require ModuleA, which avoids causing the recursive require.
I found a kinda hacky loophole for this
in your other module, instead of requiring it, add the table you want in the functions so that it effectively keeps all information from the other module