Difference between do-end and {} blocks

Posted by Moser on 07 Feb 2010

There is a important difference between the two block syntaxes in Ruby: Their precedence. Consider following code:

def method1(*args)
  puts "method1 got a block" if block_given?
end

def method2(*args)
  puts "method2 got a block" if block_given?
end

method1 method2 do
end

method1 method2 {
}

You would expect both method calls to produce the same result, wouldn’t you? Output:

method1 got a block
method2 got a block

Obviously the do-end block is passed to the first method in the expression while the {} block is passed to the method called directly before it. Another example shows that the assignment does not count as a method call here:

#[...]
class Foo
  def bar=(o)
    puts "Foo#bar= got a block" if block_given?
  end
end
foo = Foo.new

foo.bar = method1 method2 do
end 
#method1 got a block

foo.bar = method1 method2 {
} 
#method2 got a block