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.