Reputation: 2151
From p.226 of Russ Olsen's Eloquent Ruby:
All of the variables that are visible just before the opening do or { are still visible inside a code block. Code blocks drag along the scope in which they were created wherever they go.
To see this for myself, I ran the following code
class Foo
def initialize
@a = 1
end
def show_a
puts "from method: value of a is #{@a}"
yield
end
end
bar = Foo.new
bar.show_a {puts "from block: value of a is #{@a}"}
The output, to my surprise, is
from method: value of a is 1
from block: value of a is
Why is the value of @a not making it into the block?
Upvotes: 0
Views: 74
Reputation: 237060
Right before bar.show_a {puts "from block: value of a is #{@a}"}
, stick in a puts @a
. That will be nil as well. You will find that there is no @a
instance variable visible in that scope, because @a
is an instance variable of the Foo class. So the block is faithfully reflecting the lack of an @a
in the surrounding scope.
To put it another way: A block closes over the scope where it's created, not where it's called.
Upvotes: 3