7

loop { break } can work fine, but

block = Proc.new { break }
# or
# block = lambda { break }
loop(&block) # => LocalJumpError: break from proc-closure

Is it possible to break in a block variable ?

Update:

A example to explain more:

def odd_loop
    i = 1
    loop do
        yield i
        i += 2
    end
end

def even_loop
    i = 2
    loop do
        yield i
        i += 2
    end
end

# This work
odd_loop do |i|
    puts i
    break if i > 10
end

# This doesn't work
break_greater_10 = Proc.new do |i|
    puts i
    break if i > 10
end

odd_loop(&break_greater_10) # break from proc-closure (LocalJumpError)
even_loop(&break_greater_10) # break from proc-closure (LocalJumpError)

As my comprehension, Proc.new should work same as block (it can return a function from block), but I don't understand why can't break a loop.

P.S. Sorry for my bad english >~<

Steely Wing
  • 14,459
  • 6
  • 54
  • 51

2 Answers2

7

To solve this problem you could

raise StopIteration

this worked for me.

Jazz
  • 1,190
  • 14
  • 11
  • 1
    +1 Not only does it work, it's actually used in an [example in the ruby docs](http://ruby-doc.org/core-2.5.3/StopIteration.html) to halt a `loop`. – Kelvin Dec 21 '18 at 21:22
3

To return from a block you can use the next keyword.

def foo
  f = Proc.new {next ; p 1}
  f.call
  return 'hello'
end

puts foo     # => 'hello' , without 1
halfelf
  • 8,964
  • 13
  • 49
  • 61