When to use blocks

ruby

Solution

The whole thing would be more readable as:

if something.do_stuff
  #successful code
else
  #unsuccessful code
end

or to use a common rails idiom:

if @user.save
  render :action=>:show
else
   @user.errors.each{|attr,msg| logger.info "#{attr} - #{msg}" }
   render :action=>:edit
end

IMHO, avoiding the return of a boolean value is overuse of code blocks.

A block makes sense if . . .

It allows code to use a resource without having to close that resource

 open("fname") do |f|
  # do stuff with the file
 end #don't have to worry about closing the file

The calling code would have to do non-trivial computation with the result

In this case, you avoid adding the return value to calling scope. This also often makes sense with multiple return values.

something.do_stuff do |res1, res2|
   if res1.foo? and res2.bar?
      foo(res1)
   elsif res2.bar?
      bar(res2)
   end
 end #didn't add res1/res2 to the calling scope

Code must be called both before and after the yield

You see this in some of the rails helpers:

 <% content_tag :div do  %>
     <%= content_tag :span "span content" %>
  <% end -%>

And of course iterators are a great use case, as they're (considered by ruby-ists to be) prettier than `for` loops or list comprehensions.

Certainly not an exhaustive list, but I recommend that you don't just use blocks because you can.

Problem

I love Ruby blocks! The idea behind them is just very very neat and convenient. I have just looked back over my code from the past week or so, which is basically every single ruby function I ever have written, and I have noticed that not a single one of them returns a value! Instead of returning values, I always use a block to pass the data back! I have even caught myself contemplating writing a little status class which would allow me to write code like : ``` something.do_stuff do |status| status.success do # successful code end status.fail do # fail code puts status.error_message end end ``` Am I using blocks too much? Is there a time to use blocks and a time to use return values? Are there any gotchas to be aware of? Will my huge use of blocks come and bite me sometime?

Original source