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.