Ruby Block Bindings (Block Scope)

Ruby blocks have access to the current scope bindings (local variables, instance variables, and self) that exist when the block is defined. Blocks are ‘defined’ when methods are called. Let’s start with a simple example:

x = 'bob'
r = ['a', 'c']
# block has access to the local variable x
r.each {|e| e.replace(x)} # block is defined when each() method is called

The following example illustrates how a block has access to the local variables, instance variables, methods, and self when it is defined:

def a_method
  yield
end

x = 42
@y = 33

def hi; 'hey'; end

# block has access to current scope bindings when it's defined
a_method do
  p "self: #{self}" # => "self: main"
  p "x: #{x}" # => "x: 42"
  p "y: #{@y}" # => "y: 33"
  p "hi(): #{hi}" # => "hi(): hey"
end

Blocks can define additional bindings and these are lost once the block is finished executing. In other words, local variables defined in a block are only available within the block.

def yielder
  yield
end

yielder do
  # create a new binding (z) for the block
  z = 'zee'
  p z # => "zee"
end

# binding from the block is no longer available
p z

When local variables and block variables conflict, the block variable is used.

def yielder
  yield
end

a = 'aaa'

yielder do |a| # block variable conflicts with local binding
  a = 'zzz'
  p a # => 'zzz'
end

Blocks generally use the bindings that are in existence when the block is defined, except when an existing binding conflicts with a block variable and the block variable is used. Additional local bindings can be defined within a block and these will be lost when the block is finished executing.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s