Scope and More Resources

Table of Contents

Scope defines where in a program a variable is accessible.

  1. Scope
  2. Scope and Methods
  3. Scope and Blocks
  4. Resources

Scope

When a variable is accessible it is said to be “in scope”. Wherever a variable is not accessible by your program it is said to be “out of scope” or “outside the current scope.”

From the Poignant Guide:

“Microscopes narrow and magnify your vision. Telescopes extend the range of your vision. In Ruby, scope refers to a field of vision inside methods and blocks.”

Scope and Methods

Variables can be passed into a method as arguments. But, methods cannot ‘see’ variables defined outside its scope.

Data can also be returned from a method. But, variables defined within a method are only accessible until the method ends.

# How many legs are there in total if we have
# 'creature_count' number of 'creature's?
def leg_count creature, creature_count
  if creature == 'human'
    legs = 2 * creature_count
  elsif creature == 'spider'
    legs = 8 * creature_count
  else
    legs = 4 * creature_count
  end
  "#{legs} #{creature} legs in total."
end

puts leg_count 'spider', 4
puts legs # This variable should not be available in the current scope.

Output:

32 spider legs in total.
NameError: undefined local variable or method 'legs'

Scope and Blocks

Unlike methods, blocks can ‘see’ and modify variables that are defined in their vicinity. This can lead to confusing code:

fruit = 'dragon fruit'   # The fruit variable *will not* be overwritten by the loop.
double_fruit = fruit * 2 # The double_fruit variable *will* be overwritten by the loop.

['apple','pear','banana'].each do |fruit| # Creates a second fruit variable with a separate scope.
  double_fruit = fruit * 2  # double_fruit refers to the variable defined above the block.
  puts "I ate one #{fruit}. Doubled: #{double_fruit}"
end

puts "It's true I ate one #{fruit}." # Still 'dragon fruit'
puts "But the double fruit is #{double_fruit}!" # 'bananabanana'

Here the double_fruit variable within the block was the same variable as the one defined above.

But there were two versions of the fruit variable! It’s confusing when block arguments have the same name as other variables.

Output:

I ate one apple. Doubled: appleapple
I ate one pear. Doubled: pearpear
I ate one banana. Doubled: bananabanana
It's true I ate one dragon fruit.
But the double fruit is bananabanana!

Resources

Free Ruby EBooks

Ruby Tutorials

Ruby Reference