In Ruby, variable scope is defined by a block (see Local Variable Scope). A block is usually delimited by curly brace
However this is not always the case:
Code delimited by
do/end is considered a block if the delimiters follows a method invocation.
arr = [9, 8, 7, 6] # Array initialized to variable arr in the outer scope arr.each do # Block passed as an argument to the `Array#each` method b = 3 # Variable b initialized in the inner scope end puts b # NameError (undefined local variable or method `b' for # main:Object) because of scope rules
Blocks are a way to pass chunk of codes around in our program. This programming technique is called closure.
Blocks are alike anonymous functions in Java.
Let’s now take a look at the code below:
arr = [9, 8, 7, 6] # Array initialized to variable arr in the outer scope for i in arr do # for keyword b = 3 # Integer 3 assigned to variable b end puts b # 3
While it would seem
for...do/end creates a new inner scope, it is actually not the case.
for is a keyword part of the Ruby language and not a method invocation.
This is why in this case, even though it is followed by
do/end, no block are being defined.