Archive for the ‘ruby’ Category

Do or do not… or maybe try?

Wednesday, June 28th, 2006

During RailsConf, _why presented the last two installment of his fabulous series: The Least Surprised. This time, they even were multimediatically animated, with sound and movement.

In one of them, Malsky (that’s his name) talks about exception handling and compares Java’s wimpy, tentative try (”uhm… let’s see, are we suppose to be doing this?”) and catch (”oh, oh, they threw a ball at me… don’t close your eyes… don’t close your eyes…”) with ruby’s assertive and daring begin (”we’re on a mission, here we go”) and rescue (”something went wrong, but it’s ok, we can deal with it”). And he finished with a “in ruby, there is no try” and a round of applause. I’m paraphrasing here, trying to fetch the memories behind a cloud of drunken stupor, but I’m sure it was pretty much like that, if not literally, at least in spirit.

So, anyway, after his totally and amazingly rocking performance, I approached him. Once I got the autograph out of the way, I showed him this little nugget of code we use at streeteasy.

module Kernel
  # Returns 'value' in case of an exception, otherwise returns the execution
  # of the given block
  def try(value = nil)
    yield if block_given?
  rescue Exception => exception
    value
  end
end

Which provides the simplest possible exception handling: in-line inside your expressions, with a default value in case of any exception. Some examples are in order:

try {params.join} || ""
try("") {params.join}
"User: #{user} (#{ try {user.group.name} || "no group" })"
user.group = try {Group.find(params[:id])}

See? a clean way of dealing with “minor” exceptions. And _why, after clarifying that it was Malsky’s opinion, not actually his, agreed that “it was tentative enough, and an apropriate use of trying”, and that the || syntax was prettier (we agree).

So now, our source code looks like this:

module Kernel
  # Returns 'value' in case of an exception, otherwise returns the execution
  # of the given block
  #
  # Now with the official stamp of approval of _why the lucky stiff
  #
  def try(value = nil)
    yield if block_given?
  rescue Exception => exception
    value
  end
end

Feel free to use it in your code, and try to give us credit (heh, see, a pun). Why not? (heh, another pun, I’m funny).