Ruby Blocks

In this article we will discuss how default arguments work and analyze a situation where they can be useful.

The Ruby block

Ruby blocks are code that can be run by other code. All methods can accept blocks, but it’s up to them whether they do something with them or not.

3.times { puts 'hello world' }
3.times do
  puts 'hello world'
end

Blocks can take parameters

Ruby blocks accept parameters and can also initialize them with default values.

def call_block(&block)
  block.call
end

call_block do |greeting = "hi"|
  puts "Block value: '#{greeting}'"
end

In the example above, we initialize the local block variable greeting with the value “hi”.

The behavior can be demonstrated more easily if we use procs:

is_even_proc = Proc.new {|n=1| n%2 == 0 }

is_even_proc(2) # => true
is_even_proc()  # => false, which is the default behavior

Usefulness

For a real example let’s consider the shared examples feature from RSpec, the well know gem for behavior driven development inside the Ruby ecosystem. So, when we use shared_examples we can define a default value and thus avoid code duplication.

# pseudocode

shared_example success |cost=0|
  it "processes the order" do
    expect_any_instance_of(Product).to receive(cost)
  end
end

# Can be used with or without cost

it_behaves_like :success, 1
it_behaves_like :success

Conclusion

To sum up, Ruby allows blocks to receive parameters and enables its initialization with default values. This is applicable is some real world scenarios, such as DRYing up our RSpec suite.