2011-01-13 23 views
5

Với phương pháp sau đây:Cách trả về (a_method ||: other) trả về: chỉ khác khi gán cho một var gọi là a_method?

def some_method 
    :value 
end 

Các câu sau đây làm việc như tôi mong chờ:

some_method || :other 
# => :value 

x = some_method || :other 
# => :value 

Nhưng hành vi của các tuyên bố sau làm bối rối tôi:

some_method = some_method || :other 
# => :other 

Nó tạo ra một biến cục bộ được gọi là some_method như mong đợi và các cuộc gọi tiếp theo tới some_method trả về giá trị của loca đó l biến. Nhưng tại sao nó chỉ định :other thay vì :value?

Tôi hiểu rằng đó có thể không phải là điều thông minh để làm, và có thể thấy nó có thể mơ hồ như thế nào, nhưng tôi nghĩ rằng phía bên tay phải của nhiệm vụ cần được đánh giá trước khi phân công được xem xét ...

Tôi đã thử nghiệm điều này trong Ruby 1.8.7 và Ruby 1.9.2 với kết quả giống hệt nhau.

Chúc mừng!

Paul

+0

"Tôi nghĩ rằng phía bên tay phải của bài tập phải được đánh giá trước bài tập". Đó là, nhưng nó là bên tay phải của dấu '=', không phải toàn bộ dòng. 'some_method' sẽ được đánh giá để xem nếu nó có một" sự thật "đầu tiên, và, nếu có, điều đó sẽ được trả về. Nếu không thì ': other' sẽ được xem xét. Các toán tử Boolean như '||' và '&& 'đôi khi có vẻ tùy ý vì cách một ngôn ngữ cụ thể xác định" sự thật ". Ví dụ, Perl xác định nó khác với Ruby, vì vậy bạn phải nhận thức được sự khác biệt nếu bạn sử dụng cả hai ngôn ngữ. –

Trả lời

5

Có các câu hỏi tương tự nhưng không chính xác như nhau. Jörg's answer đây dường như nhấn điểm, tôi trích dẫn một phần có liên quan:

Tại thời điểm này, foo được định nghĩa, thậm chí dù dòng sẽ không bao giờ bị thực thi. Thực tế là dòng không bao giờ được thực hiện hoàn toàn không liên quan, bởi vì thông dịch viên không liên quan gì đến điều này: biến cục bộ được xác định bởi trình phân tích cú pháp và trình phân tích cú pháp rõ ràng thấy dòng này.

Vì vậy, trong trường hợp của bạn, bất kể phương thức có cùng tên đã tồn tại, trình phân tích sẽ thấy chuyển nhượng some_method và tự động "gắn thẻ" định danh là biến cục bộ. Vì vậy, khi thông dịch viên bắt đầu đánh giá phía bên phải của nhiệm vụ, nó đã xem xét some_method là biến cục bộ, không phải là một phương thức. Giá trị của nó chưa được gán (nil theo mặc định), do đó kết quả của || sẽ là :other.

+0

>> đã xem some_method là biến cục bộ.với một giá trị sai, do đó: khác được chỉ định. – noodl

+0

Phải (chỉ với giá trị không xác định thay vì sai), tôi đã chỉnh sửa câu trả lời cùng một lúc khi bạn viết nhận xét. :) –

+1

@noodl: Tôi nghĩ nó sẽ là 'nil', không phải' sai'. –

4

Một câu trả lời đơn giản là: tuyên bố cuối cùng của bạn cũng giống như

some_var = some_var || :other 

bởi vì khi bạn có một biến địa phương trong phạm vi có cùng tên như một phương pháp, người phiên dịch cho các ưu tiên biến cục bộ.

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