2013-03-15 40 views
6

loop { break } có thể làm việc tốt, nhưngLàm thế nào để `phá vỡ một vòng lặp bên ngoài trong đóng cửa (Proc, lambda)?

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

Có thể break trong một block variable?

Cập nhật:

Một ví dụ để giải thích thêm:

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) 

Như hiểu của tôi, Proc.new nên làm việc tương tự như khối (nó có thể return một chức năng từ khối), nhưng tôi không hiểu tại sao không thể phá vỡ một vòng lặp.

P.S. Xin lỗi vì tiếng anh xấu của tôi> ~ <

+0

Bạn muốn đạt được điều gì với điều này? –

+0

99% liên quan: http://stackoverflow.com/questions/626/when-to-use-lambda-when-to-use-proc-new – tokland

+0

@Sergio Xem cập nhật, @tokland Tôi biết sự khác biệt trong 'Proc. new' và 'lambda', tôi đang yêu cầu' break' trong 'closure' –

Trả lời

3

Để trở về từ một khối bạn có thể sử dụng từ khóa next.

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

puts foo  # => 'hello' , without 1 
+0

' break' một vòng lặp bên ngoài là sự trở lại khác nhau từ khối –

+2

Trong trường hợp của bạn, bạn có thể sử dụng 'lambda' và sử dụng' return', tôi nghĩ 'tiếp theo 'không tốt cho điều này (mặc dù nó hoạt động) –

3

Để giải quyết vấn đề này, bạn có thể

raise StopIteration 

này làm việc cho tôi.

Các vấn đề liên quan