2013-07-23 28 views
31

Sự cố với mã Ruby 2.0 này là gì?Trả lại bất ngờ (LocalJumpError)

p (1..8).collect{|denom| 
    (1...denom).collect{|num| 
     r = Rational(num, denom) 
     if r > Rational(1, 3) and r < Rational(1, 2) 
      return 1 
     else 
      return 0 
     end 
    } 
}.flatten 

Lỗi này nằm trong block (2 levels) in <main>': unexpected return (LocalJumpError). Tôi muốn tạo một danh sách phẳng chứa n những người (và số 0 còn lại) trong đó n là số lượng số hữu tỷ với mẫu số dưới 8 là từ 1/3 đến 1/2. (it's a Project Euler problem). Vì vậy, tôi đang cố gắng trở về từ khối bên trong.

+2

Không sử dụng 'return' trong một khối. Chỉ cần loại bỏ cả hai 'return' và mã của bạn sẽ được ok. – oldergod

Trả lời

37

Bạn không thể return bên trong một khối trong Ruby *. Báo cáo kết quả cuối cùng sẽ trở thành giá trị trả về, vì vậy bạn chỉ có thể loại bỏ những điều khoản trở lại trong trường hợp của bạn:

p (1..8).collect{|denom| 
    (1...denom).collect{|num| 
     r = Rational(num, denom) 
     if r > Rational(1, 3) and r < Rational(1, 2) 
      1 
     else 
      0 
     end 
    } 
}.flatten 

*: Bạn có thể bên trong lambda khối: lambda { return "foo" }.call # => "foo". Nó phải làm với phạm vi và tất cả những điều đó, và đây là một trong những khác biệt chính giữa các khối lambdaproc khối. Các khối "bình thường" bạn chuyển tới các phương thức giống như các khối proc.

+55

Bạn * có thể * sử dụng 'return' bên trong một khối trong Ruby. Nó sẽ trở về từ phương pháp kèm theo. Trong trường hợp này, có * không có * phương pháp kèm theo, * đó là * tại sao có lỗi, đó là * không * vì 'trả về' trong một khối là bất hợp pháp. –

+0

@ JörgWMittag Bạn nói đúng, tôi đã đơn giản hóa. 'return' trả về cho phương thức gần nhất * hoặc *' lambda' mà bạn đang ở trong đó. Nếu bạn không ở bên trong, bạn sẽ nhận được 'LocalJumpError'. – henrikhodne

+0

@ JörgWMittag cảm ơn lời tuyên bố rõ ràng này. Câu trả lời là khó hiểu và bạn đã làm rõ nó. Tôi hiểu tại sao lỗi này xuất hiện dễ dàng. –