rubyscopeblock

What is the purpose of setting Ruby block local variables when blocks have their own scope already?


Learning about Ruby blocks [here][1]. What is the point of having block local variable in this example:

x = 10
5.times do |y; x|
  x = y
  puts "x in inside the block: #{x}"
end
puts "x outside the block: #{x}"
x in inside the block: 0
x in inside the block: 1
x in inside the block: 2
x in inside the block: 3
x in inside the block: 4
x in outside the block: 10

When you can just do the below instead? The x in the block is already going to have its own scope, which is different than the x that is outside the block.

x = 10
5.times do |x|
  puts "x in inside the block: #{x}"
end
puts "x outside the block: #{x}"

The resulting output is the same.


Solution

  • Block scopes nest inside their lexically enclosing scope:

    foo = :outerfoo
    bar = :outerbar
    
    1.times do |;bar|
      foo = :innerfoo
      bar = :innerbar
      baz = :innerbaz
    end
    
    foo #=> :innerfoo
    bar #=> :outerbar
    baz # NameError
    

    You need a way to tell Ruby: "I don't want this variable from the outer scope, I want a fresh one." That's what block local variables do.