I dont really understand the whole locals/non-locals things in scripts.
For example, some scripts I see have local before the function/script
and some dont.
I dont really understand the difference, and it would be great if someone could thoroughly explain it to me- I am kind of new, anways.
Thanks!
Alright, so there are differences between the two types of variables. If you're familiar with a language such as Java or C, then you'd have heard of 'private' and 'public' variables. This is essentially the same thing.
Although, if you do not know either of those languages, I'll elaborate.
A 'private' variable can only be accessed within the current scope, for example:
function hi()
local troll = 'hi';
end;
hi();
print(troll); -- nil
This is because the variable troll is local, or rather private.
A 'public' variable can be accessed throughout the entire script:
function hi()
troll = hi;
end;
print(troll); -- hi
This works because it is a global variable this time. It would help you to look into the variable documentation to better understand this (on the wiki).
I've given a brief outline at the bottom:
local/private: can only be accessed within the current scope. global/public: can be accessed throughout the entire script.
Hope this helped!
The idea of a local variable comes from the idea of scope.
The scope of a name (or equivalently, the data associated with that name, as in a variable) means where/when you can use that name to refer to that thing.
The default scope of variables (that are not iterators in for
loops or function parameters) is global.
That is, they are not local
--- their scope is the entire script (hence, global)
In good code, in modern programming languages, scopes are limited -- that is, they aren't the entire script (global).
Scopes are limited so that:
For example, consider this function:
function hypotenuse(a,b) c2 = a^2 + b^2 c = math.sqrt(c2) return c end
Let's write some other code that makes use of it; in specific, we'll look at two versions of this code that are exactly the same, we just renamed some variables:
x = 3 y = 4 z = 12 print(z) -- 12 print( hypotenuse(x, y) ) -- 5 print(z) -- 12 print( hypotenuse(y, z) ) -- 12.64911 -- a = 3 b = 4 c = 12 print(c) -- 12 print( hypotenuse(a, b) ) -- 5 -- `hypotenuse` *changed* `c`! print(c) -- 5 -- !!!!!! print( hypotenuse(b, c) ) -- 6.403124 -- !!!!!!!
The output from them is different!
This isn't a reasonable result, since Lua shouldn't care what we name the variables.
Because hypotenuse
writes to c
, it also modified the c
we were using to store triangle side lengths.
The reason for this is that the c
in the last example is the same c
as it appears in hypotenuse
(even though they ought to have nothing to do with each other)
It's sometimes called "poisoning" the scope when this happens -- calling hypotenuse
damages other variables. We don't want that -- we want the c
in hypotenuse
to only be the c
in hypotenuse.
We denote that by declaring c
as local
which means its scope extends only within the current block (thing marked by end
or until
)
Here's what a fixed hypotenuse
would look like:
function hypotenuse(a, b) -- parameters are already local and are fine how they are -- (no worries about a and b) local c2 = a^2 + b^2 -- declare new variables as local local c = math.sqrt(c2) return c end a = 3 b = 4 c = 12 print(c) -- 12 print( hypotenuse(a, b) ) -- 5 print(c) -- 12 print( hypotenuse(b, c) ) -- 12.64911 -- This time it's all consistent with how it should be!
By default, the iterating variables of for
loops and function parameters are already local
.
Since functions are usually only declared at the top level, making them local
doesn't usually accomplish anything.
Best practice: Always use local
. It helps keep things neater and it also helps you mentally keep track of where variables should be used for the first time.
TL;DR:
local
on variables (the first time you declare them)local
(normally)local
lets same variable name be used in 2 placeslocal
) (causing problems, see 3rd bullet)Alright, Lets Look at the Variable 'local'
Lets look at a simple script with local in it
while wait() do -- Loop starts for _,v in pairs(game.Players:GetChildren()) do -- V stands for players local humanoid = v.Character:findFirstChild("Humanoid") -- This Makes the Humanoid of your Character Aquired by saying 'humanoid' throughout the script if humanoid then local head = v.Character:findFirstChild("Head")-- Creates a New Variable(Not a Variable just couldnt think of the word)that allows you to Find The Part Head if head then head.Mesh:Destroy() -- This will error Sooner or later, because it has already been Deleted, Dont worry doesnt effect the script end end end end -- Loop Ends here
Throughout this whole script I used Two 'local's It made it a Lot easier For me to Grab the mesh, and Delete it in Each character, If Anymore Help is needed PM me.