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
  • 16,239
  • 8
  • 58
  • 54

2 Answers2

7

To solve this problem you could

raise StopIteration

this worked for me.

Pilo
  • 1,210
  • 15
  • 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
  • 9,737
  • 13
  • 54
  • 63