Oops simple mistake

I have been trying to get values from a module script and while I was trying things out I realized that one of the parameters turned into a falsy value.

This image shows the call to the module script. Data is already defined to the script and this is calling a function in it. p is the player value. I have tried and using

if p then print("is true") end

does give the print message. However,

this shows me trying to use the added player parameter to find out this does not return a true value. This is somewhat strange and I would like some help and knowledge.

Here I asked why the parameter changed from what I originally called it with.
But changing : to . fixed the parameter problem but since I thought that self would simply be the first parameter and it doesn’t override the manual first parameter. So now Im here asking for some knowledge so I can understand this a bit better.

If you’re changing between ‘.’ and ‘:’, make sure the script is doing it as well when calling it.

If you’re calling module.Function() when it’s a method (‘:’), it wouldn’t work.
Vice versa I assume.

Oh wow I completely forgot about this part. Thanks for the help

1 Like

It’s because : calls a function with self automatically as the first argument, while . does not. For example:

game:GetService("Workspace")
-- is equivalent to
game.GetService(game, "Workspace")

Since you aren’t using ., you have to pass game (which is self, aka the item the function is being called on) as the first argument manually. This applies to all functions:

local instance = Instance.new("Part")

instance.Destroy(instance)
-- is the same as
instance:Destroy()

However, you should always use : if it is meant to be used. Luau optimizes method calls, which means using : is considerably faster than using . and passing self manually.

This is a feature of lua and it is typically used to make OOP classes using metatables/metamethods.

1 Like

The question is already solved. I didn’t use the same : when I called the function

I know, I’m explaining why this happens rather than just telling you how to fix it.

Even if you don’t want the help (you should, the title of the post clearly conveys that you didn’t understand this concept prior) other people that may find this post in the future will still benefit from the extended explanation.

1 Like

It has already been answered but a bit more explanation.

module:function() is syntax sugar for module.function(module). So when you call a module using : you’re actually typing module.function(module).

Now when the function itself in the module is written using : it unlocks a new keyword names self.
This self keyword is a table to the module. For example:

local module = {}
function module:foo()
   print(self) --> returns this module with the functions foo and bar
end
function module.bar()
   print(self) --> returns nil
end

module:foo()
module:bar()

Now remember how calling functions using : was the same as giving the module as the first parameter? This is only the case if the function in the module was written with a dot. For example:

local module = {}
function module:foo(param1, param2)
   print(self, param1, param2)
end
function module.bar(param1, param2)
   print(param1, param2)
end

module:foo(1) --> prints: the module, 1, nil (since the : with : doesn't provide the module)
module.foo(1) --> prints: 1, nil, nil (self is now 1 not param1, since the : assumes the first argument is the module itself, and calling with . doesn't provide the module)

module:bar(1) --> prints: this module, 1
module.bar(1) --> prints: 1, nil (since it doesn't provide the module as the first argument)

Now to be safe, just make sure you call the function with the same character as you made it with and the parameters won’t change.

IN SHORT.
If you made the function with :, it expects the first parameter to be the module itself. self will become the first parameter given to the function.
If you made the function with ., it will act like a normal function, self will be nil.
Calling functions with : will automatically make the first parameter the module itself and shifts all other parameters (1 will become 2 etc).
Calling functions with . will not modify any parameters.

Here’s a quick lookup table.

made with :, called using : | self will be the module, param1 will be param1
made with :, called using . | self will be param1, param1 will be param2 etc
made with ., called using : | self will be nil, param1 will be the module, param2 will be param1 etc
made with ., called using . | self will be nil, param1 will be param1
2 Likes