Local and Global Variables
Since the lesson on variables, you've written local before every variable, and we promised to explain why. Now that you write functions, it's time.
Every local variable has a scope: the part of the program where it exists. The scope starts on the line where the variable is created and ends with the block it was created in: the body of a function, of an if or of a loop, or the whole program. Parameters are local variables of their function. So a variable created inside a function doesn't exist outside it:
local function countEggs()
local eggs = 12
print("In the barn: " .. eggs)
end
countEggs()
print(eggs)This prints:
In the barn: 12
nilOutside the function, there's no eggs, so the last line prints nil. Each call of a function creates its local variables anew, and they disappear when the function ends. That's useful: two functions can each have their own variable total, and they never get in each other's way.
The other way around, a function sees the local variables created above it, outside the function, and it can even change them:
local coins = 10
local function buySeeds(price)
coins = coins - price
end
buySeeds(3)
buySeeds(2)
print(coins)This prints:
5And what about a variable without local? coins = 50 creates a global variable. A global variable belongs to no block: from the moment it's created, it exists everywhere, in every function, until the program ends. Lua's own print, math and table are global variables too; that's why you can use them anywhere. When Lua doesn't find a local variable with some name, it looks for a global one, and when there isn't one either, the value is nil. That's why calling a function too early gave the error attempt to call a nil value (global 'morningChores').
Global variables look handy, but they cause bugs that are hard to find:
- A typo creates a new variable. Because a variable can be created without
local, Lua can't tell a typo from a new variable.cions = coins + 5isn't an error: Lua quietly creates a global variablecions, andcoinsdoesn't change. - Anything can change them. Any function, anywhere in the program, can change a global variable, so when its value is wrong, you have to search the whole program. Even
printcan be overwritten: afterprint = 5, everyprint(…)ends with the errorattempt to call a number value (global 'print').
The worst case is a forgotten local inside a function:
local function sellEggs(eggs)
coins = eggs * 2
return coins
end
coins = 50
local earned = sellEggs(10)
print("Earned: " .. earned)
print("Coins: " .. coins)This prints:
Earned: 20
Coins: 20Emma had 50 coins, and after selling eggs she has 20? The function wanted a variable of its own, but without local, the coins inside the function is the same global variable as outside, and the function overwrote it. With local coins = eggs * 2 in the function, these would be two different variables, and Emma would keep her coins.
That's why this course writes local before every variable and every function (function sellEggs without local creates a global function). Each variable then exists only where it's needed, and no function can change another one's variables by accident. Values go into a function through its parameters and come out with return. As a bonus, Lua finds local variables faster than global ones. Just remember that the scope starts on the line with local: a function can only use local variables and local functions created above it.
Instructions
Emma's hens laid eggs every day, but the program prints Eggs this week: 0. In countEggs, a variable name has a typo. Lua didn't report it: it quietly created a global variable. Find the typo and fix it. The program then prints Eggs this week: 49.
Now the program prints Earned: 98 coins and Coins: 196. But Emma had 50 coins, so she should have 148. The variable coins in sellEggs has no local, so the function overwrites Emma's coins from the top of the program. Fix the function so that it uses a local variable of its own. The program then prints:
Eggs this week: 49
Earned: 98 coins
Coins: 148The function sellEggs itself is still global. Make it local, like countEggs. The program prints the same.
Start programming for free
6/11