Sometimes the scope of a local variable is a bit confusing when working with blocks. For example, the following will result in an “undefined local variable” for variables “x” and “bacon”

(1..10).each do |x|
  bacon = "Turkey"
end

puts x
puts bacon

Both are variables defined within a block and will be local to the block. They’re not accessible outside of the block. However, if you were to put “bacon” outside of the block:

bacon = "Canadian"

(1..10).each do |x|
  bacon = "Turkey"
end

puts bacon

The output would be “Turkey.” The block could change the value of a local variable in its surrounding scope. The variable “x” on the other hand is a block parameter and is always local to the block. So even if you define “x” in the surround scope, it would not adjust its value:

x = "Cheddar Cheese"

(1..10).each do |x|
  ...
end

puts x

# The output would be "Cheddar Cheese" instead of a numeric.

Now what if you want to use the variable “bacon” inside the block without having it affect the surrounding scope’s assignment? Fortunately you could tack on a semi-colon in the block parameters list and follow it with variables you want to reserve within the scope of the block:

bacon = "Canadian"

(1..10).each do |x; bacon|
  bacon = "Turkey"
end

puts bacon 

# The output would be "Canadian"

The variables defined after the semi-colon are protected from being changed in the surround scope.

Hope this clears it up for people running into weird block issues.