Using 'return' in a Ruby block Using 'return' in a Ruby block ruby ruby

Using 'return' in a Ruby block


Simply use next in this context:

$ irbirb(main):001:0> def thing(*args, &block)irb(main):002:1>   value = block.callirb(main):003:1>   puts "value=#{value}"irb(main):004:1> end=> nilirb(main):005:0>irb(main):006:0* thing {irb(main):007:1*   return 6 * 7irb(main):008:1> }LocalJumpError: unexpected return        from (irb):7:in `block in irb_binding'        from (irb):2:in `call'        from (irb):2:in `thing'        from (irb):6        from /home/mirko/.rvm/rubies/ruby-1.9.1-p378/bin/irb:15:in `<main>'irb(main):009:0> thing { break 6 * 7 }=> 42irb(main):011:0> thing { next 6 * 7 }value=42=> nil
  • return always returns from method, but if you test this snippet in irb you don't have method, that's why you have LocalJumpError
  • break returns value from block and ends its call. If your block was called by yield or .call, then break breaks from this iterator too
  • next returns value from block and ends its call. If your block was called by yield or .call, then next returns value to line where yield was called


You cannot do that in Ruby.

The return keyword always returns from the method or lambda in the current context. In blocks, it will return from the method in which the closure was defined. It cannot be made to return from the calling method or lambda.

The Rubyspec demonstrates that this is indeed the correct behaviour for Ruby (admittedly not a real implementation, but aims full compatibility with C Ruby):

describe "The return keyword" do# ...describe "within a block" do# ...it "causes the method that lexically encloses the block to return" do# ...it "returns from the lexically enclosing method even in case of chained calls" do# ...


You are looking it from the wrong point of view.This is an issue of thing, not the lambda.

def thing(*args, &block)  block.call.tap do |value|    puts "value=#{value}"  endendthing {  6 * 7}