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?