How to call functions in a ModuleScript like a script function?

Hello! I’m trying to call a function in a ModuleScript that’s required by a script like a function that’s inside the script.
local module = {}

module.Something = function()
print(“hello!”)
end

module.OtherThings = function()
print(“bye!”)
end

return module
That’s the ModuleScript.

Now normally if you require the ModuleScript in a script, you would call the functions like this:
requiredModule.Something()

However, I would like to call the functions like this for simplicity’s sake:
Something()

I know this is possible with a non table returned by the ModuleScript, but I don’t want like 500 ModuleScripts piling up to be required.

Things I tried already:
setfenv() - It completely wiped roblox’s lua environment.
metamethods - Can’t find a suitable function.

Thanks.

Don’t do this! You can use getfenv to inject into the script environment, but that the cost of missing out on some of Luau’s optimizations. You also won’t get good IntelliSense.

3 Likes

May I know how? I never knew this before.

Sure, check this out:

(ctrl + f “getfenv” to get there quicker)

You can do

local module = require(yourModuleHere)
local Something = module.Something
local OtherThings = module.OtherThings

or

local Something, OtherThings = unpack(require(yourModuleHere))

Also to make a code block use

```lua
[code]
```

1 Like

I tried using unpack, but now it says:
ServerScriptService.setfenv test:2: attempt to call a nil value

Here’s the script that’s requiring the module:

local Something, OtherThings = unpack(require(script:WaitForChild("LIB TEST")))
Something()
OtherThings()

My bad, currently all the table library functions only work with arrays and not dictionaries so you’ll have to use the first method I provided or you can make a custom unpack function but that seems extra and unnecessary.

I think you could do it without performance penalties like this:

(This is just @Kabutey second method, but with unnamed functions to preserve array keys so unpack works.)
Module:

local module = {
	function (...) --Something
		print("Something.")
	end,
	function (...) --Other thing.
		print("Other thing.")
	end,
}

return module

Script:

local Something, OtherThing = unpack(require(script:WaitForChild("ModuleScript")))

Something()
OtherThing()

The caveat is that if you ever update the module, changing the order of the functions will certainly cause things to break in a confusing way. Also, you have to name all the functions in the script whenever you require them.

Overall, I don’t think it’s a great idea, but it is possible. Maybe someone else knows a better way to do it?

1 Like

I usually do like this:

ModuleScript:

local module = {}

function module.Hello()
    print("Hello!")
end

return module

Script:

local ModuleScript = --Path of the ModuleScript
require(ModuleScript).Hello()
3 Likes

I would highly advise against this due to the extremely annoying red lines that will pop up in IntelliSense, and other problems that might arise, but…

Enjoy.

local function env_require(module)
	for k,v in next, require(module) do
		getfenv()[k] = v
	end
end

env_require(path.to.module)

Something()
local requiredModule = require(module)
local Something = requiredModule.Something

Something()