Type 1:
local var = nil
function foo()
print(var)
end
var = 10
foo()
Type 2:
function foo()
print(var)
end
var = 10
foo()
Is there any advantage of doing the type 1?
I’ve been doing it all the time and I can’t figure out why…
Type 1:
local var = nil
function foo()
print(var)
end
var = 10
foo()
Type 2:
function foo()
print(var)
end
var = 10
foo()
Is there any advantage of doing the type 1?
I’ve been doing it all the time and I can’t figure out why…
Using local variables means you’re not polluting the global scope, and is generally better code practice. Especially when you can confine the scope of the local
tighter than “the entire file”, for example:
function foo()
local result
for i = 1, 10 do
if math.random(1, 10) == 0 then
result = true
break
end
end
print(result)
end
If you don’t declare a local here, it means that anywhere else in the file that you use a variable with the same name will interfere. It also means that the value won’t be initialized to nil when the function is called.
In cases where your local
is in the top level scope, it’s at least consistent with using local
elsewhere in the file.
One important thing to note is when you’re working with Lua outside of Roblox, assigning to variables that haven’t been declared with local
puts them into _G
and makes them shared with other modules such as those that you require()
.
Most Lua linter tools consider non-local variables bad practice because of this, including our own script analyzer. It makes local reasoning close to impossible because the variable may have been set from literally anywhere in the file, and it makes it difficult to impossible to tell whether a variable has actually been defined before using it. This is especially relevant because it makes it difficult to tell if e.g. instance
is a typo of Instance
or simply a variable you’ve declared.
I recently had to send someone this example and he said it was very useful so here ya go
local a = 1
local b = 2
local function test()
local c = 3
local b = 4
d = 4
print(a, b, c, d) --> 1 4 3 4
end
test()
print(a, b, c, d) --> 1 2 nil 4
So basicallly in roblox, defining local variables at the top of your script is simply to make your code look clean?
It has no actual effect in terms of safety from hackers etc (Hai all hackers reading my posts )?
Well, it’s more than just aesthetics. Local variables have faster access than global variables. Also, local and global functions behave slightly differently. Sometimes you will have to forward declare local functions in order for your code to work properly. This caused me a few headaches many years back.
As for security, if nothing else it’s probably safer to use local variables, since they are stored on the stack and not in the function environment. However I’m not an expert in this area, so I am unsure to what extent this would improve security.
You’re saying type 1 is stored on stack but type 2 is not?
Aren’t they in same scope being they are in topscope of the script?
‘Global’ variables are accessible by getfenv
and setfenv
, the function environment. Local variables are not. getfenv
and setfenv
in a nutshell allow you to treat global variables like they were stored in a typical table. Actually, getfenv
returns such a table. I digress.
They are in the same scope, yes, but they are handled much differently C-side. They aren’t as similar as they look.
test = function()
print(test)
end
If you run the above, it will print the found function.
However, this next code will print nil:
local test = function()
print(test)
end
If you do this little trick called forward declaring, you can work around the issue:
local test
test = function()
print(test)
end
Note that this is still a local variable even though the actual declaration did not have the local prefix.
According to learncpp’s website,
A forward declaration tells the compiler that an identifier exists before it is actually defined.
For basically every case (Barring usage of the function environment) it is a good policy to stick to local variables.
I thought Roblox localizes variables in the global scope by default now?
Nope. Run this code on ROBLOX:
d = 0
print(getfenv(0).d) --> 0
local e = 0
print(getfenv(0).e) --> nil
I could of sworn I think zeuxcg talked somewhere about automatic localization