It was not until today that I finally read and understand how parameters/arguments of functions work. However, I don't understand how they work when the function is declared as it is called. For example:
ClickDetector.MouseClick:connect(function(clicked) local Sgui = Instance.new("ScreenGui", clicked.PlayerGui)
The parameter "clicked" is never defined as a value since the function is called then and there. Yet this script will work to make a ScreenGui appear inside the localplayer's PlayerGui. How does it know what "clicked" is?
:connect
is not a straightforward use of functions -- it isn't using functions like they normally are.
This is a really good question -- this is a weird bit of code, and it's a little disappointing not many learning scripters realize how strange it looks.
I'm going to use the Touched
event as in my examples, but it works the same way as the MouseClick
event.
First, let's write our connection separately from the definition of the function:
function makeRed( part ) part.BrickColor = BrickColor.red() end workspace.Wall.Touched:connect( makeRed )
part
is defined, in the scope of the makeRed
function, to be the first value that makeRed
is given when called.
First of all, ignoring the :connect
line, we can just use makeRed
ourselves:
makeRed(workspace.Player1.Torso) makeRed(workspace.BasePlate)
The first line, part
will be the player's Torso; the second line, it will be the BasePlate.
Here's something Lua lets us do. It's called first class functions or higher ordered functions (EDIT: had serious nomenclature typo)
function makeRed( part ) part.BrickColor = BrickColor.red() end function makeBlue( part ) part.BrickColor = BrickColor.blue() end local changer if math.random(2) == 1 then changer = makeRed else changer = makeBlue end -- Notice that we did not CALL either makeRed or makeBlue -- We just used the *function itself* as a *value* (just like -- I can use variables like `workspace` or `ClickDetector`) changer( workspace.BasePlate ) -- half the time will be red, half the time will be blue
What happened here? changer
now stores the value of a function -- that means when we call changer
, it will actually be calling the function we assigned it to, which was either makeRed
or makeBlue
.
:connect
does a similar thing. When you say :connect( makeRed )
, you aren't calling makeRed
. You're giving the value of makeRed
so that ROBLOX can call it later.
Here's a fake implementation of how .Touched:connect( x )
might work:
function connect( xfun ) while wait() do local near = getNearestPart( workspace.Wall ) if areTouching(near, workspace.Wall) then xfun( near ) -- Here! end end end
How does it know what [the parameter's value] is?
Somewhere, :connect
is calling your function with a parameter -- :connect
tells your function what the parameter is, in the same way that functions normally get their parameters
Higher ordered functions are awesome. Here's an aside on the makeBlue
and makeRed
we had earlier:
function makeColorChanger( str ) return function(part) part.BrickColor = BrickColor.new(str) end end makeRed = makeColorChanger("Bright red") makeBlue = makeColorChange("Bright blue") makeGreen = makeColorChange("Bright green") -- etc! -- Let's make the baseplate red: makeRed( workspace.BasePlate ) -- OR: makeColorChanger("Bright red")(workspace.BasePlate) -- Funny looking, but awesome that it works
The parameter is the player who clicked. (It isn't the LocalPlayer -- a "Script" object (as opposed to a LocalScript) doesn't have the concept of a LocalPlayer)
ROBLOX obviously can know who clicked it, since the game has to know it was clicked at all (so it just also adds, "it was this guy"). So ROBLOX just informs the event of that information.
Notice in this link that the parameter is playerWhoClicked
.
The MouseClick event's parameter returns the player model. This is a built-in feature of this event.
Another such example is the HealthChanged event. The example uses health
as the parameter as the value "Health" is changed to.
Truth be told, I don't really know. I pretty much assumed that's how some events behave.