Monday, August 3, 2009

next as a way to return from a block

In Ruby, you can't return from a block with return; this will instead return from the enclosing method; if there is no enclosing method (i.e. you are at toplevel), this will throw an error.

However, the Ruby next statement takes an argument, and seems to work as a means to return from a block without breaking out of any enclosing context.

Demonstration:

def yielder
 ret = yield
 puts 'After yield'
 return ret
end

Now from irb:

>> VERSION
=> "1.8.6"

>> yielder{1}
After yield
=> 1

>> yielder{return 1} # This tries to return from toplevel...
LocalJumpError: unexpected return

>> yielder{break 1} # This breaks completely out of the call to yielder...
=> 1

>> yielder{next 1; puts 'In block'} # Aha! This breaks out of the block but stays in the method!
After yield
=> 1

As an example of how this can be useful:

  mixed_collection.sort do |x,y|
    next x.class.name <=> y.class.name if x.class != y.class
    x <=> y
  end

My main question at this point is, does this work in Ruby 1.9?

Update: Works in Ruby 1.9.1

No comments:

Post a Comment