Last Updated: February 25, 2016
· mcansky

Ruby : block as parameter

A coworker asked me to refactor some code using a block passed as parameter to a method.

If you are not familiar with Ruby blocks the thing is you can bundle up some lines of code inside a "do-end" block (or {} if it's a one line or if you like to mess up with your brain).

Using blocks is fun, it's a nice way to bundle up a series of actions :

[1,2,3].each do |i|
  puts i
  i += 2
  puts i

But you can also write a method that will take a block as parameter. The method can then run the block at any time by calling yield :

def foo_m(_a, &block)
  if (_a % 2) == 0
    puts "hooray"

[1,2,3,4,5].each do |i|
  foo_m i do
    puts "something is odd here"

what's happening ?

The foo_m method is simple : it outputs "hooray" if the a parameter is an even number and *yield if that's not the case. When the method yields it then pass the hand to the block, or rather we could say "it runs the block". So when the _a is odd the string "something is odd here" will be outputted.

To me it feels both awesome and strange as the block code will only be run if the method does yield at some point. And there lies the strangeness of the thing : it makes the code a bit difficult to read : it's not "straightforward" (to me).

What do you think ? Is there a better way to explain this and to keep the code readable ?