I am currently trying to make my own version of roblox’s require. However i cannot figure out how to make a recursive function that is efficient.
I am trying to get to a specific path via a recursive function. An example of this function would be: get(“folder1/folder2/module”). All of these folders are located inside of the main ‘get’ module and i would like some help. Here is my code so far and a picture of the structure:
local function FindPath(path, curDir)
curDir = curDir or script
local finalDir = nil
for _, v in pairs(curDir:GetChildren()) do
if v.Name == path[#path] and v:IsA("ModuleScript") then
return require(v)
end
finalDir = v
end
return FindPath(path, finalDir)
end
return function(path: string)
if path == "all" then
local modules = {}
for i, module in pairs(script:GetDescendants()) do
if module:IsA("ModuleScript") then
modules[i] = require(module)
end
end
return modules
else
path = string.split(path, "/")
return FindPath(path)
end
end
Here is an example of how i intend to use it:
local util = get("sys/interact/interactUtils")
local mouseUtil = get("util/mouse")
You probably shouldn’t use a recursive function here. A loop will work just fine. Try this:
-- Requires the module from the given path
function Require(path, dir) -- dir is optional, defaults to script
local hierarchy = string.split(path, "/")
dir = dir or script
for _, v in ipairs(hierarchy) do
if dir:FindFirstChild(v) then
dir = dir[v]
else
error("Could not find "..path)
end
end
return require(dir)
end
If you want to require a set of modules you can try this:
-- Requires the module(s) from the given path
function Require(path, dir) -- dir is optional, defaults to script
local hierarchy = string.split(path, "/")
dir = dir or script
for _, v in ipairs(hierarchy) do
if dir:FindFirstChild(v) then
dir = dir[v]
elseif v == "*" then
local modules = {}
for _, descendant in ipairs(dir:GetDescendants()) do
if descendant:IsA("ModuleScript") then
modules[descendant.Name] = require(descendant)
end
end
return modules
else
error("Could not find "..path)
end
end
return require(dir)
end
-- Use example
local util = Require("sys/interact/interactUtils")
local otherUtils = Require("util/*") -- Requires and returns all module descendants of 'util'
local mouseUtil = otherUtils.mouse
Using ‘path/subpath/ModuleName’ would return a single required module, or you could use ‘path/subpath/etc/*’ to get a set of module scripts within a directory including its subdirectory chain. Or you could just use “*” to get all modules in the input directory and the table returned stores each required module by its name.