How to turn a module into a function?

I am fairly new to module scripts. Right now, to make functions in module script I do it like this:

local module = {}
function module:Function()

end
return module

and call it like this:

local module = require(script.Module)
module:Function()

It would work perfectly, but I have seen in some modules you call functions like:

local module = require(script.Module)
module()

How can I do it like that?

1 Like

Simple.

return function()
...
end

or

local function newFunction() -- call it whatever you want
...
end

return newFunction

You can return ANY type in a ModuleScript. A table is just the most common.

return "insert string here"

or

return 1
2 Likes

How can I return both, the function and the module? So it is like:

module(args)
module:Part("Name")

You can only return one value. That’s just how it works. Think of a ModuleScript as a function. It only runs when you require it, it can (and has to) return a value. And it runs all the code inside of it when it is called. (require)

You can return the value in the function too.

What about return Function,module?
Will that work?

Alternatively if you don’t need the use of OOP you can use

local module = require(script.Module)
local Func = require(script.Module).Function
Func()
1 Like

Yeah, that’s also a viable option.

The __call metamethod would work well for what you are trying to achieve.

local module = setmetatable(
{--the module itself
--whatever your module contains
},
{--the metatable
__call = function(self,...)
--self is the module, ... are the parsed arguments
end
})
return module

The thing to consider is that if you call it as a method (module:Part()), the first argument will be “Part”.

2 Likes

Yeah you can do that.

local func, module = require(...)

I think I will use a table instead as an alternative:

return {Function,module}

That works, but before we go so deep into metatables we probably would need to ask “why?” does he want to do this specific thing.
Is he trying to solve a problem?
Just learning?
or some kind of programming aesthetic choice?

3 Likes

This post was incorrect, do not listen to what I said.

Original Post

You can still return 2 values, not two return statements.
I misread your question.

return module, function
1 Like

I don’t think you can return more than one value in a module.

Metatables are the best choice for what he wants to do, as described above by @nooneisback.

1 Like

Metatables are nevertheless a good thing to know even for beginners. They are confusing for people who got used to other languages, but are actually really simple to understand. They can also solve pretty much any issue with little work.

Not for me though. I am not used to any other languages.

Yeah metatables are some of THE most useful things in lua, but at the same time I wouldn’t recommend teaching them to a beginner.

O yes definitely, I just don’t encourage them willy nilly cause there is an overhead to using them and can unnecessarily complicate code.

1 Like

I tested this. ModuleScripts must return exactly one value. So multiple returns even in a single statement don’t work.

The function has to be in a table if you want multiple objects to be returned.

1 Like

They are meant to stuff all the complicated code behind and abstract class. It is easier to use something without actually understanding it. The overhead is pretty much the only issue I see with them, though it is actually really small and only makes a difference when often accessing the object.

@mobyboyy They are literally just tables with functions or values that get called/returned in specific cases. They are fairly easy to understand.

@StrategicPlayZ As I said above, metatables are just tables that contain values that are meant to replace a default function of tables (and userdatas, but you don’t need those in Roblox). You can read the “metatable” article on the DevHub, but I’m going to make a basic run down of what each of them does.

There are multiple metamethods that can be placed into a metatable and all of them get “activated” in certain conditions.

__index: This will fire every time you try to access the table.
If you set a function to it, it will fire with two arguments: the original table and the index of the value you tried to get.
If a table is set to it, a value from that table will be returned instead.

__newindex: This one gets called when you set a new value to your table. Good for checking if a valid value is added. The arguments are: table, index, value.

__call: This allows you to use a table as a function. If you apply this, calling a table like tab() will no longer error as it reroutes your arguments to the set function. Arguments: table, method name (optional), other arguments.

There are also math and logic metamethods which allow you to add, subtract or check if the two tables are equal. Neat for implementing custom classes.

There are also other metamethods, but they aren’t as important.

1 Like

I wasn’t fully sure, I should have mentioned that.