Directly connecting global (_G) functions don't work, but indirectly they do

Let’s say I have a global function named “Arda”:

_G.Arda = function(var)
    print(var)
end

and in a different script I connect it to a mouse-button-one event like this:

Button.MouseButton1Click:Connect(_G.Arda("lol"))

yet it gives this error:

…attempt to call field ‘Arda’ (a nil value)…

However, if I connect the function to the event like this:

Button.MouseButton1Click:Connect(function()
    _G.Arda("lol")
end)

it works! Now I am thinking of two occasions: either I am blind, or there is something wrong. I thought the first occasion seems much more likely, so I posted this here instead of bug reports.

:Connect(_G.Arda("lol")) attempts to connect the return value of the call, which is nil. It has nothing to do with _G.

6 Likes

This is probably because you’re trying to access _G.Arda before you’re assigning it. If you wait() prior to Button.MouseButton1Click:Connect(_G.Arda("lol")), does the original error disappear? (for another one to pop up, as Kamp mentioned)

1 Like

You’d want to avoid _G in this case because of race conditions, unless you properly set it up. wait() might work but is a bad solution.

2 Likes

@Dandystan @Kampfkarren You guys are right, I added a delay at the first line of the script, and the error message changed into:

Attempt to connect failed: Passed value is not a function…

I actually have never attempted to use _G before, but now it looks handy to me to prevent writing similar stuff over and over again. Sorry for the noob question.

This is the point of ModuleScripts. Give reusable code a ModuleScript and require it. Not only does this stop race conditions, but it also makes it obvious where your code is coming from.

4 Likes

I do not recommend using _G because of situations like this. With larger projects, code bases that rely on the table tend to become quite messy and hard to work with, too.

A similar, but much more manageable and scalable, alternative is to use ModuleScripts to create a modular system.

Thank you guys, I am switching to module scripts the day I started using _G. You may have saved me from future issues, so thank you again!

@Kampfkarren answer is correct. For those who are still confused and to propose a solution in regards to the original question, you could write Arda’s function as:

function(var)
    return function()
        print(var)
    end 
end

Functions may return other functions in this pattern. You’d need to pass a function into the :Connect method. Passing a nil value to connect to is not something the signal is able to use.

This new revised function could exist in _G, or as others have proposed, in a ModuleScript


OP’s other example

Button.MouseButton1Click:Connect(function()
_G.Arda(“lol”)
end)

works because you are wrapping Arda in a function just like the snippet above

2 Likes

According to the error, the original issue wasn’t actually caused by passing nil to RBXScriptSignal:Connect, but by _G.Arda being nil at the time of the call. This mistake would have appeared after the first was fixed, regardless.

2 Likes

Yes, there were a few different issues at play in the original post it sounds like.

1 Like