This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
jakylorhide's profile picture

[Lua]Variables, how to use Local variables and why they are good

Started by jakylorhide, 24 April 2013 - 11:14 AM
jakylorhide #1
Posted 24 April 2013 - 01:14 PM
I am somewhat new to the whole CC scene and Lua in general. but I thought I would share something I found that makes life very easy, this is the use of local versus global variables.

Now, if you've done your homework and looked at the variables section of the wiki you see a somewhat cryptic comment about what local variables do, but (if your like me) it doesn't really explain much.

basically, lua will keep track of a huge amount of data using the "global" table _G (I think that's the name) that is referenced and written to for global variables. so if you set a global variable in one program, run it. and then try to use a different variable in another program, you'll get what was set in the first. This can be VERY VERY BAD. So we use local variables, that stay just long enough for the program to use them, before going away so that they don't screw with anything later.

There is some other fun things with Local variables shown in the script below:

Spoiler



local k = 1 --Sets local variable "k" to 1
  function i1()
	k = k + 1 --Changes the "k" by +1
	return k --[[Tells it to implement the change
	in k when asks to print or needed to be used ]]
  end

  function i2()
	local k = k + 2 --[[Changes "k" by +2 for i2()
	only]]
	return k
  end

print(k.. ", current variable k") -->1
print(i1().. ", k after i1") -->2
print(k.. ", current variable k") -->2
print(i2().. ", k after i2") -->4
print(k.. ", current variable k") --[[ >2 , note
	i2 didn't change it.]]
print(i1().. ", k after i1") -->3
print(k.. ", current variable k")-->3

if you look at the functions i1() and i2() you see only two differences, the value it changes, and one calls k as a local variable. What this means is that when the program runs it
1) sets "k" to the value 1 for this program only
2) when i1() runs, it increases the value of "k" by one for the entire program
3) when i2() runs the first time, it references "k" used for the whole program, but only changes "k" for this single run of the program
4) when i1() runs again, it references the outer "k", not the one made by step 3
5) when i2() runs again, it again references the outer "k" from step 4, not the "k" from step 3, even though it is the same function.

This can be very useful when making pathfinding programs or alternative movement apis. Basically anytime that you need to reference and change a value, but only for a certain function, without needing to duplicate it.
Bubba #2
Posted 24 April 2013 - 01:23 PM
Overall, this is good knowledge that people should have. I do have a few things to add though:

I'm not sure if what I'm about to say applies to LuaJ, but it should also be noted that there is a marked difference in speed between accessing/writing global variables. Check out this article if you're interested in the specifics and for more speed optimizations.

I see a lot of people using global variables and it often annoys me, but that's more because I'm a perfectionist and less because global variables are bad, per se. Having variables persist across programs isn't really dangerous, unless you make a coding error that you have difficulty identifying because a variable has been set in another program and you forgot to assign it in the current one. In general, it's pretty unlikely that this will happen, but why take the risk? Just localize where possible.

Another thing, you can localize functions (and essentially everything else) in Lua as well:

local function myFunc(arg)
  print(arg)
end

One place that this can come in handy is when making APIs - if you don't want to expose all the functions of your API to the "public", just make them local and they will be effectively invisible.

And one last thing, local variables are "trashed" upon exiting their running environment. In a huge application I suppose this would make a speed difference, but in general it probably doesn't matter much for CC. It does keep security to a maximum though.

Edit: Oops, guess I'm not quite done. Although global variables are stored in the global environment, the _G table is only a representation of the global environment. In other words, if I change a variable directly in the _G table by doing something like the following:

x = 5 --Make a global variable
_G["x"] = 3 --"Change" it to 3
print(x) --Print out x

The above code will output "5", because I only changed what is stored in the _G table, not the actual global environment. If I want to change the values of the global table directly, I can use setfenv as in the following example:

setfenv(1, _G) -- The 1 signifies the stack level at which I am changing the environment
x = 5
_G["x"] = 3
print(x) --Outputs "3"
NanoBob #3
Posted 30 April 2013 - 05:13 PM
is a local variable set on your ingame computer?
and if you set a variable in a program example:

x=cookies

is it also set on the entire ingame computer for all prograns?
or is it only set in the program you type the code (x=cookies) in?
Bubba #4
Posted 30 April 2013 - 08:16 PM
is a local variable set on your ingame computer?
and if you set a variable in a program example:

x=cookies

is it also set on the entire ingame computer for all prograns?
or is it only set in the program you type the code (x=cookies) in?

If you are playing on a server, all computer data is stored on the host (this includes local variables). If you create a global variable, such as x="stuff", it will be available to all programs until you restart the computer.
NanoBob #5
Posted 01 May 2013 - 05:13 AM
so if you set a local variable , it is set on all computers on the server?
Bubba #6
Posted 01 May 2013 - 09:57 AM
so if you set a local variable , it is set on all computers on the server?

No, just on that particular computer on the server.
NanoBob #7
Posted 01 May 2013 - 03:09 PM
ok thanks.