I know from all my studying that a FunctionFires an Event, But what is the Difference between: Local Function, and a Regular Function?
NOTE: The ROBLOX Wiki did NOT Provide an Answer for this.
I know from all my studying that a FunctionFires an Event, But what is the Difference between: Local Function, and a Regular Function?
NOTE: The ROBLOX Wiki did NOT Provide an Answer for this.
adark missed the biggest practical different between local functions and not.
Global variables can be used lexically (in order in source) before they were declared. For instance,
function blah()
print( a ) -- where a is a global (not local) variable
end
a = 5
blah()
-- 5
local variables are only usable after them (lexically -- in source order):
local a = 5
blah()
-- nil
The same applies to local functions -- they can only be used after they are declared, thus the following is invalid:
function blah()
print( a() )
end
local function a()
return 5
end
blah() -- a() will cause "attempt to call a nil value"
In addition, it lets you hide functions entirely:
do
local function blah(x)
return x + math.random()
end
function save(x)
return blah(x)
end
end
print(save(5)) -- 5.432426812304
print(blah(5)) -- attempt to call a nil value
According to Programming in Lua, the following two are equivalent:
local function name()
--body
end
local name; name = function()
-- body
end
To be honest, I didn't know about the out-of-order execution thing myself.
There is no difference between 'local' functions and 'normal' functions, actually.
First, a bit of clarification: Functions do not fire events, they listen to them. The ROBLOX engine itself fires them, passing in relevant information as arguments. Also, Function is invalid, as Lua is case-sensitive.
What's going on is a shortcut of Lua:
function Name(params)
--end
end
--Is the EXACT SAME as:
Name = function(params)
--end
end
Functions are first-class values in Lua, meaning that you can treat them as any other kind of variable. If you are familiar with C, Lua functions are more accurately function pointers.
This is why you'll see code like this:
loadstring(str)() --Where 'str' is a string of valid Lua code
The first set of parentheses calls loadstring, which returns a Lua function. The second set of parentheses calls that function.
As you probably know, the local keyword in Lua indicates the scope of a variable. If not, let me explain:
var1 = true --Global variable. In many implementations, this would be shared across 'Scripts'. Not in ROBLOX, however.
local var2 = false --Local variable, to the script. Functionally identical to the above, since the 'scope' is the entire script. Is slightly faster to access.
do
var3 = "Red Fish" --Global variable. Even though it is declared inside of a code block, it is accessible outside of it.
local var4 = "Blue fish" --Local variable. *Not* accessible outside of this code block.
print(var1) --> true
print(var2) --> false
--Variables are always available in "child" blocks, like this one.
end
print(var3) --> Red Fish
print(var4) --> nil
--var4 goes out of scope here, so we cannot access it.
do
local var2 = "Yellow Fish"
local var3 = "Pink Fish!!!"
--Local variables "override" higher-scoped variables.
print(var2) --> Yellow Fish
print(var3) --> Pink Fish!!!
end
print(var2) --> false
print(var3) --> Red Fish
--Local overrides go out of scope, and the original values are `restored`.
When you make a function local, the same rules apply. Using top-level local variables in place of globals gives a considerable performance increase after a while, so that's why it's common to see them.
One last word on functions, and Tables as well:
Unlike other variables types, functions and Tables are, effectively, pointers. This is why you get something like this when you try to print them. When you pass a Table or function around as an argument to some function call, you are actually passing a reference to the Table/function. Any other variable type is copied into a function's 'upvalues', which are the parameters:
local function RunThis(tableParam, functionParam, otherParam)
tableParam[27] = true
otherParam = otherParam .. "YOLOSWAGGY"
print(tableParam)
print(functionParam)
print(otherParam)
end
local str = "String"
local tab = {"Test1", "Test3"}
print(str) --> String
print(tab[27]) --> nil
print(tab) --> table: XXXXXXXA
print(RunThis) --> function: XXXXXXXB
RunThis(tab, RunThis, str) --> table: XXXXXXXA, function: XXXXXXXB, StringYOLOSWAGGY
-- I use 'RunThis' twice here. The first access is called as a function, indicated by the ()'s, but the second is merely referenced as a Variable.
print(str) --> String
print(tab[27]) --> true
print(tab) --> table: XXXXXXXA
print(RunThis) --> function: XXXXXXXB
tab and RunThis are pointers, to a Table and a function, respectively. RunThis() calls the function at the end of the pointer.
Notice, modifying the str upvalue passed into the RunThis call does not modify the external str variable. Modifying the Table's members, however, does modify the external Table. It is not possible (AFAIK) to modify the external function using just its upvalue.
A further note on upvalues: they act as local variables, following the rules above, so:
local tab = {}
local tab2 = {}
function RunThis(tab, X)
tab = {X = 25, Y = 17}
X.X = 26
X.Y = 17
X = {}
end
RunThis(tab, tab2)
print(tab.X) --> nil
print(tab.Y) --> nil
--The `tab` upvalue in the function *overrides* the higher-scoped `tab` declaration on line 1.
print(tab2.X) --> 26
print(tab2.Y) --> 17
--The same thing here. Even though we set X to an empty Table at the end of the function, that simply overrode the upvalue.
And, finally, reusing local variables:
In the above code, you'll notice that I did not write local X = {}. This is because X is already local. Since it was declared in the function definition as an upvalue (remember, parameters are upvalues), rewriting it in the 'global' scope simply reuses whatever scope the variable already had.
This is because variables in Lua do not have a specified Type. That is,
local x = true
x = "false"
x = 261
Is all valid Lua. In a language like C, that kind of code would produce a compile error, as x is either a Boolean or a String or an Integer, and definitely not all three at once.
All three of those x declarations are local, because the initial declaration is. When a higher-scoped variable is overridden, the most recent scope is used:
local x = 27
function RunThis()
x = 45 --Same var as on line 1. If this code were all wrapped in a code block, this would not be accessible outside of it.
local x = 18 --New scope, to this function.
x = "BOOLEAN" --Same scope as the line above, *not* the same as Line 1.
end
RunThis()
If you've been paying attention thus far, you'll realize that you can declare functions inside of code blocks:
function makeFunction(str)
local function func()
print("yolo" .. str)
end
return func
end
makeFunction("swag")() --> yoloswag
And as members of Tables:
local tab = {}
tab.Func = function()
--code
end
--Or:
function tab.Func2()
--code
end
This second case is how you can make methods as opposed to functions:
tab = {Applesauce = true}
function tab.func(t)
print(t.Applesauce)
end
function tab:func2(appl) --Note the `:` here.
self.Applesauce = appl --"Method declaration" gives you a `self` parameter.
end
--This function is identical to:
function tab.func2(self, appl)
self.Applesauce = appl
end
--You can call these as either functions *or* methods:
tab.func1(tab) --> true
tab.func2(tab, "Hooligans!") --Although we edit the Table passed to the function, and not `tab`, this works because only the Table *reference* is sent, not a copy of the Table.
tab:func1() --> "Hooligans!"
tab:func2(true)
--And, finally, you can actually use *other* tables in these functions calls:
local tab2 = {}
tab.func2(tab2, "Peanuts")
tab.func1(tab2) --> Peanuts
Local functions are more optimized, and should be used where possible.
Please have a Better description, I couldn't quite understand that.
Please view this article http://wiki.roblox.com/index.php?title=Performance, A locally referenced function is quicker and easier for Lua to access than a global scope one.
This discussion is preserved as it was. New answers, comments, and votes are closed.
3 comments
I guess that local functions are not stored in the server while normal functions are. I'm not so sure though
You go to the wiki to find out, and then you script it.
yoshi, I just said that the ROBLOX Wiki did not provide an answer.