Variable Scope: What You Will Learn

In the last lesson, you returned values from functions so the caller could decide what to do with the result. As a quick reminder, that approach made your code more flexible and reusable. Today, you will learn another key building block: variable scope. Scope controls where a variable can be seen and used. You will see how local and global variables work in Lua, how shadowing happens, and why avoiding globals keeps your programs safer.

Scope in Action: Local vs Global (and Shadowing)
-- This is a global variable, accessible everywhere. Avoid these!
travel_mode = "Plane"

local function plan_trip()
    -- This is a local variable, only accessible inside this function.
    local destination = "Hawaii"
    print("Local destination: " .. destination)
    
    -- This local variable 'shadows' the global one inside this function.
    local travel_mode = "Ship"
    print("Local travel mode: " .. travel_mode)
end

plan_trip()

-- Trying to access the local variable from outside its scope does not give you its value; instead, you are reading a global variable named `destination`, which is `nil` because it was never set. 
-- In Lua, accessing an undeclared variable returns `nil`, but to avoid an error, we check if it exists.-- In Lua, accessing an undeclared variable returns nil, but to avoid an error, we check if it exists.
if destination == nil then
    print("Global destination: nil") -- Prints: Global destination: nil
else
    print("Global destination: " .. tostring(destination))
end

-- The global variable was not affected by the local one inside the function.
print("Global travel mode: " .. travel_mode) -- Prints: Global travel mode: Plane

Explanation:

  • travel_mode is declared without local, so it becomes global. It can be accessed anywhere. While Lua allows this, you should avoid globals because they are hard to track and can be changed by any part of the program.
  • Inside plan_trip, destination is declared with local. It exists only inside the function. Printing it works there, but it disappears after the function finishes.
  • The local travel_mode inside plan_trip shadows the global travel_mode. Inside the function, the local value ("Ship") is used; outside, the global value ("Plane") remains unchanged.
  • plan_trip() runs the function, so you can see the local prints first.
  • After the call, destination does not exist globally. In Lua, reading an undeclared variable yields nil. The if check prints a clear message instead of trying to concatenate nil to a string (which would cause an error).
  • The final print shows the global travel_mode is still "Plane." The local shadow did not modify it.

Note: If you want to change a global variable inside a function, just assign to it without using local. For example, travel_mode = "Car" inside a function would update the global variable. Using local travel_mode = "Car" would instead create a new local variable that only exists inside the function.

Guidelines to remember:

  • Prefer local variables by default. They are safer and limit unintended side effects.
  • Only use globals when you have a strong reason and clear naming.
  • Be careful with shadowing; it is legal but can be confusing if overused.
Summary and Next Steps

You learned how scope controls visibility:

  • Local variables live only where they are declared (like inside a function).
  • Global variables are visible everywhere and should be used sparingly.
  • Shadowing lets a local variable temporarily hide a global with the same name.
  • Accessing an undeclared variable yields nil in Lua, so handle it safely.

Great work building on your function skills with clean scoping habits. Head to the practice section to apply these ideas and gain confidence using locals, globals, and shadowing in real code.

Sign up
Join the 1M+ learners on CodeSignal
Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal