'What is the purpose of setting Ruby block local variables when blocks have their own scope already?
Learning about Ruby blocks here. What is the point of having block local variable in this example:

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.

Solution 1:[1]
The point they're trying to make is that a block local variable (or a block parameter) will be completely separate from the variable outside of the block even if they have the same name, but if you just refer to x within the block without it being a block local variable or a block parameter, you're referring to the same x that exists outside the block.
They have this example right above the one you cite:
x = 10
5.times do |y|
x = y
puts "x inside the block: #{x}"
end
puts "x outside the block: #{x}"
Output:
x inside the block: 0
x inside the block: 1
x inside the block: 2
x inside the block: 3
x inside the block: 4
x outside the block: 4
Note that this is only the case if you refer to x before the block. If you removed the x = 10 line at the beginning, then the x in the block would be completely local to the block and that last line would error out (unless you had a method named x in the same object, in which case it would call that method).
Solution 2:[2]
I feel like the examples given in the original post leave a lot to be desired and largely serve to further confuse matters because the results of |y; x| and |y, x| are going to be identical. So the obvious question becomes this:
Why would we ever need to use a semicolon to create a block local variable if simply creating a regular block variable does the same thing?
I think the answer is that you would want to use ; instead of , anytime you want to BOTH protect the outer variable from manipulation AND declare an inner variable that will NOT be passed to the method.
Consider for example what happens with multiple assignment or hash when working with the map method:
x = 10
array = [[1], [:a]]
hash = {:b => 2}
array.map {|y| x = y} #=> [[1], [:a]]
x #=> [:a]
array.map {|y, x| x = y} #=> [1, :a]
x #=> 10
array.map {|y; x| x = y} #=> [[1], [:a]]
x #=> 10
hash.map {|y| x = y} #=> [[:b, 2]]
x #=> [:b, 2]
hash.map {|y, x| x = y} #=> [:b]
x #=> 10
hash.map {|y; x| x = y} #=> [[:b, 2]]
x #=> 10
Solution 3:[3]
The examples above are teaching you about block scopes and how inner scopes can mute outer scopes (your x variable). The point is that you have to be aware of the differences.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | Michael B |
| Solution 3 | Ahmed Masud |
