This is an old topic, but I often see people converting blocks to procs in method arguments, when there is no need to:
There is a performance hit in the first example, because we are converting a block to a Proc object behind the scenes. Let’s have a look:
Now to the results:
user system total real
With an explicit block 15.010000 0.160000 15.170000 ( 15.598784)
With an implicit block 6.200000 0.040000 6.240000 ( 6.361095)
We can see here that an implicit block is more than twice faster. It is idiomatic Ruby, and readability isn’t very compromised. Some people prefer to have blocks at the paremeter list, but if you use short methods this is not a problem, as you can easily see the yield keyword inside the method.
You will also know that the method needs a block, because it will throw a no block given (yield) (LocalJumpError), if there are cars in the collection and you don’t supply a block.
When to use an explicit block
There are some legitimate reasons to prefer explicit blocks.
You want to store the block for later use
A snippet of code is worth a thousand words:
You don’t want to duplicate knowledge about yielded arguments
You may want to convert a block into a Proc when delegating it to another method, specifically when you don’t want your proxy method to have knowledge about yielded arguments. Let’s have a look at a bad example:
This is a bad example, because whenever we change the Renderer block parameters we’ll also need to modify the proxy render method, to reflect changes in the argument list.
Instead we turn our block into a Proc object, then turn the Proc back to a block when delegating it to the Renderer constructor:
The main advantage in that aproach is that the render method doesn’t need to know anything about the block arguments - it’s also easier to read and easier to reason about.
If you don’t supply a block to the render method, Ruby will assume the block argument is nil: when it delegates the block to the Renderer constructor, it does a Renderer.new(setup, &nil) behind the scenes, and the constructor will assume no block is given.
You want flexibility
Maybe you want to do some crazy metaprogramming, inspecting your block from the inside out; maybe you want to know the block’s source location, or use a curried version of the block… or maybe you want check its arity, or whatever… you can still convert your block to a Proc object.
You want explicitness in the method arguments
If you want explicitness, just use Python. OK, I’m just kidding :)
Conclusion
Sometimes when you learn a coding technique you tend to abuse it without thinking. Let’s not do that. If you have any other reason why using an explicit block is worth, leave it in the comments.