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
nil

Outside 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:

5

And 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 + 5 isn't an error: Lua quietly creates a global variable cions, and coins doesn'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 print can be overwritten: after print = 5, every print(…) ends with the error attempt 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: 20

Emma 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: 148

The function sellEggs itself is still global. Make it local, like countEggs. The program prints the same.

Start programming for free

By signing up, you agree to the Terms of Service and Privacy Policy.

Or sign up with:

6/11