2013-03-22 15 views
11

Tôi gặp rất nhiều khó khăn khi hiểu cách hoạt động của các khối, procs và lambdas như thế nào return.Báo cáo trả lại bên trong procs, lambdas và các khối

Ví dụ: trong trường hợp sau, tại sao batman_ironman_proc hoạt động, trong khi batman_yield có lỗi?

def batman_ironman_proc 
    victor = Proc.new { return "Batman will win!" } 
    victor.call 
    "Iron Man will win!" 
end 

def batman_yield 
    yield 
    "Iron man will win!" 
end 

victor = Proc.new { return "Batman will win!" } 

puts batman_ironman_proc 
#batman_yield(&victor) === This code throws an error. 
+0

có thể trùng lặp của [Sử dụng 'trả lại' trong khối Ruby] (http://stackoverflow.com/questions/2325471/using-return-in-a-ruby-block) – mgibsonbr

+1

Tại đây: http: // stackoverflow. com/questions/1435743/why-does-explicit-return-make-a-sự khác biệt-in-a-proc – fmendez

+0

Tôi biết bạn đang học điều này từ codeacademy. Tôi có những nghi ngờ tương tự. Đó là một hướng dẫn giới thiệu phong nha, nhưng bạn phải tìm kiếm google rất nhiều để có thể hiểu được hướng dẫn. –

Trả lời

9

Như one answer trong câu hỏi liên quan cho thấy:

Các return từ khóa luôn lợi nhuận từ phương pháp hoặc lambda trong bối cảnh hiện nay. Trong các khối, nó sẽ trở về từ phương pháp trong đó đóng cửa là được xác định. Không thể thực hiện trả lại từ phương thức gọi hoặc lambda.

Ví dụ đầu tiên của bạn thành công vì bạn đã xác định victor trong cùng chức năng bạn muốn trả lại, vì vậy, return là hợp pháp trong ngữ cảnh đó. Trong ví dụ thứ hai của bạn, victor được xác định ở cấp cao nhất. Hiệu ứng của số đó return, sau đó, sẽ không phải là để trở về từ batman_yield (phương thức gọi), nhưng [nếu nó hợp lệ] để trở về từ chính cấp cao nhất (trong đó Proc được xác định).

Làm rõ: trong khi bạn có thể truy cập giá trị trả về của một khối (nghĩa là "Giá trị của biểu thức cuối cùng được đánh giá trong khối được chuyển trở lại phương thức làm giá trị của lợi nhuận" - theo nhận xét của bạn) , bạn không thể sử dụng từ khóa return, vì lý do đã nêu ở trên. Ví dụ:

def batman_yield 
    value = yield 
    return value 
    "Iron man will win!" 
end 

victor = Proc.new { return "Batman will win!" } 
victor2 = Proc.new { "Batman will win!" } 

#batman_yield(&victor) === This code throws an error. 
puts batman_yield(&victor2) # This code works fine. 
+1

cho rằng đây là trường hợp, làm thế nào để phương pháp như tìm, mà chấp nhận khối với các bài kiểm tra logic, sử dụng kết quả của những bài kiểm tra logic? (ví dụ: [1,2,3,4,8,10] .find {| num | num * num> 24}) – voltair

+0

@ user1419674 xem câu trả lời được cập nhật. Cùng một cách mã ví dụ của bạn không sử dụng 'return', bạn không phải sử dụng nó để truy cập vào việc đánh giá khối. Bạn chỉ có thể sử dụng giá trị trả về từ 'call', sử dụng nó trực tiếp (như trong mã ví dụ của tôi) hoặc gán nó cho một biến (ví dụ:' value = block.call') – mgibsonbr

+0

Điều này khá lạ đối với tôi, nhưng tôi tin rằng liên kết này cung cấp câu trả lời cho câu hỏi. [link] http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_containers.html Nó thực sự nói rằng lợi nhuận có thể cung cấp một giá trị trả về. Điều gì khiến tôi rất kỳ quặc về điều này là trong trường hợp này có vẻ như một sự trở lại rõ ràng và một sự trở lại tiềm ẩn tạo ra các kết quả khác nhau trong khối. – voltair

0

Tôi đến từ nền C và cách tôi giải thích khi bạn gọi hàm bạn đặt số hướng dẫn và đăng ký sẽ lưu giá trị trả về. Trong trường hợp proc và chặn lệnh return không được thiết lập bởi vì chúng được inlined hoặc được gọi trong cùng một phạm vi nhưng chúng vẫn có thể trả về một giá trị trả về vì đây là các chức năng độc lập. Vì vậy, nếu không có một lệnh trả về được thiết lập proc/block đang cho chúng ta một LocalJumpError trong khi nếu chúng ta chỉ muốn cung cấp cho một giá trị trở lại đó là tốt.

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