Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to `break` a outside loop in closure (Proc, lambda)?

Tags:

ruby

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 >~<

like image 728
Steely Wing Avatar asked Mar 15 '13 09:03

Steely Wing


2 Answers

To solve this problem you could

raise StopIteration

this worked for me.

like image 66
Jazz Avatar answered Nov 08 '22 01:11

Jazz


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
like image 29
halfelf Avatar answered Nov 08 '22 00:11

halfelf