On Fri, Nov 1, 2013 at 7:48 PM, gvim <gvimrc / gmail.com> wrote:
> I'm fairly new to Ruby, puzzling the value of:
>
> def sub1(x)
>   yield 5 * x
> end
>
> sub1(2) {|y| puts 3 * y }    #=> 30
>
> .... over:
>
> def sub2(x)
>   y = 5 * x
>   puts 3 * y
> end
>
> sub2(2)   #=> 30
>
> Isn't there the danger,  with passing code blocks, that half of your
> method/function/sub definition is hanging somewhere else in your code making
> it difficult to keep track of exactly what it does? How can I debug a method
> if I don't know what else it's composed of until it is called?

But that is true for _any_ method.  Blocks are just anonymous
functions.  In the same way as named functions and methods you need to
properly define what a method should do and what other methods should
do.  Joel gave an example: File.open is responsible for opening and
closing the file while the block passed may do whatever it needs to do
with the open File object (e.g. writing or reading).

Another example is Array#each: it is responsible for iterating all
elements. The block passed can do whatever it needs to do with the
current element.  Your piece of code would probably be badly
structured with a second method regardless whether it's a block or
another function - as long as you want to calculate and output 3*5*x.
If you often need to calculate 5*x then the approach with the block
might be better. But the example is really somewhat artificial.

Long time ago I wrote two blog articles which you might find helpful.
http://blog.rubybestpractices.com/posts/rklemme/001-Using_blocks_for_Robustness.html
http://blog.rubybestpractices.com/posts/rklemme/002_Writing_Block_Methods.html

Kind regards

robert

-- 
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/