Skip to content
AgileLogics
5 min read

Variable Scope

Prerequisites: Methods

Scope is the part of a program where a variable can be seen and used.

Real-world analogy: a method is a room with the door shut. Whatever you put on the table inside the room stays in that room, and you can't see the table in the next room.

Methods can't see outside local variables

In Ruby, def starts a completely new scope. A method can't read local variables defined outside it:

greeting = "Hello"

def say_hi
  puts greeting
end

say_hi

Running it fails inside the method:

hello.rb:4:in 'Object#say_hi': undefined local variable or method 'greeting' for main (NameError)

This is stricter than many languages, and it's a good thing: a method only depends on what you pass in. The fix is to pass the value as an argument:

greeting = "Hello"

def say_hi(greeting)
  puts greeting
end

say_hi(greeting)
Hello

Variables created inside a method disappear when the method returns.

Blocks can see outside variables

Blocks (do ... end and { ... }) are different: they can read and change variables from the surrounding code:

total = 0
[5, 10, 15].each { |n| total += n }
p total
30

That's what makes blocks so handy, and the Blocks lesson builds on it. A variable first created inside a block, however, isn't visible after the block ends.

Other kinds of variables

Ruby marks other scopes with a prefix, which you'll meet later: @name (instance variable, belongs to an object — Level 2), $name (global — avoid), and NAME (constant — visible almost everywhere).

Common mistakes

  • Expecting a method to change an outside variable by assigning to it. Return the new value instead, and assign it where you call the method.