Making a ModuleScript send back functions

This has confused me for the longest time. Roblox has functions in functions. Like for example:

game.Players:CreateLocalPlayer():Clone():GetPropertyChangedSignal("Name"):Connect(function())

Like I’m sorry, what? I see some modules kind of do something like this like DataStore2.

local DataStore2 = require(game.ServerScriptService.DataStore2)
DataStore2.Combine("DATA", "Saves")
DataStore2("Saves", game.Players.Warriorfoox):Get(nil)

I was wondering how it would be possible to do something like this, as I’ve tried multiple things and I just can’t figure this out. Here’s an example of what I tried, I know the use of this would be nothing, but it’s just me attempting this.

local Properties = {}

local function Tween(instance, info, data)
  game:GetService("TweenService"):Create(instance, info, data):Play()
end

function Properties:SetColor(NewColor, TweenData)
  if self.instance.Color then
    if TweenData ~= nil then
      Tween(self.instance, TweenData, {Color = NewColor})
    else
      self.instance.Color = NewColor
    end
  end
end

local PropertiesMetatable = {}
PropertiesMetatable.__index = Properties
local Instances = {}

function Instances:CreatePart(Name, Parent)
  local Part = Instance.new("Part")
  Part.Name = Name
  if Parent == nil then
    Parent = workspace
  end
  Part.Parent = Parent
  local NewInstance = {}
  NewInstance.instance = Part
  setmetatable(NewInstance, PropertiesMetatable)
  return NewInstance
end

return Instances

The usage of this that I’m trying to achieve is the following:

local ModuleScript = require(game.ServerScriptService.ModuleScript)
local Part = ModuleScript:CreatePart("Test")
local OtherPart = ModuleScript:CreatePart("Test2")

Part:SetColor(Color3.new(0, 0, 0), TweenInfo.new(2))
OtherPart:SetColor(Color3.new(1, 1, 1))

I just can’t get it to work, I am stumped and have no clue how to make this system functional. I don’t even know how to describe what I’m asking for, a Module inside of a Module of a ModuleScript? I don’t know.

I’ve tried returning a function and even a self function, making a call to another ModuleScript and I’m just stumped.

I’ll try to shed some light, as this is applicable to any coding language.

When a line of code is written with multiple methods being called. It’s the same as calling them on different lines of code. Except, calling them on different lines of code can help you gather certain values and track objects. It also helps with readability.

Code execution is a series of commands. If many methods are being called on a single line, they’re called in chronological order.

For example, let say I have the following modules.

local AdditionModule()

function AdditionModule.Add(num1, num2)
    return total = num 1 + num 2;
end

return AdditionModule;
local Player1CashModule = {}
local Cash = 50;

function GetCash()
    return Cash;
end

return Player1CashModule;
local Player2CashModule = {}
local Cash = 100;

function GetCash()
    return Cash;
end

return Player2CashModule;

If I decide to add the amount of cash from Player1 and Player 2. I could type it like this:

AdditionModule:Add(Player1CashModule:GetCash(), Player2CashModule:GetCash());

Under the hood, this is how it looks like:

AdditionModule:Add(50, 100));

This is because AdditionModule.Add(num1, num2) is being called with functions as arguments. But functions cannot be used as data, they can only be called to return data. Before the rest of the code gets executed inside of AdditionModule, it has to run both functions to receive valid data.

Writting all these functions on one line does sacrifice readability though. So a lot of people would rather do the following:

local p1cash = Player1CashModule:GetCash();
local p2cash = Player2CashModule:GetCash();
local total = AdditionModule.Add(p1cash, p2cash);

There’s more readability on what’s happening, also, there’s more flexibility on data. As calling all the methods on a single line usually means you don’t care about what’s being returned.

Also, calling multiple methods on one line does not make a performance difference. Everything is still getting called regardless. Not storing the returned data in your own variable just means that the computer is storing it in a temporary variable under the hood. (For it to reference)

Now, to analyze that line of code you posted.

game.Players:CreateLocalPlayer():Clone():GetPropertyChangedSignal("Name"):Connect(function())

As I said earlier, chronological order. At first, a LocalPlayer is being created. Whatever that function returns, the line now becomes this:

NewLocalPlayer:Clone():GetPropertyChangedSignal("Name"):Connect(function())

Next, it’s cloned. So it becomes as following:

ClonedLocalPlayer:GetPropertyChangedSignal("Name");

And so on…

Every function in that line is returning an object, and the returned object is having its methods called right away. Hope this sheds a bit of light!

2 Likes

you can also just do return function() if you’d like to keep it cleaner, not sure what op wants though
like so

--module script
local x = 1
return function()
    return x
end

--in script
local modulefunc = require(module)
print(modulefunc()) --> 1

(typing on mobile sorry if this looks bad)

1 Like