2011-12-14 20 views
7

Nếu tôi thực thi mã ruby ​​này:Ruby: phương pháp hiểu sao ghi đè và thiết lập để nil

def foo 
    100 
end 

p defined?(foo), foo 
if false 
    foo = 200 
end 
p defined?(foo), foo 

Kết quả tôi nhận được là:

"method" 
100 
"local-variable" 
nil 

Ai đó có thể giải thích cho tôi tại sao foo được thiết lập để nil sau khi không thực hiện nếu? Đây có phải là hành vi được mong đợi hoặc lỗi ruby ​​không?

+1

Phương pháp không được ghi đè và thiết lập để nil. 'puts foo()' vẫn hoạt động. Điều xảy ra là một biến cục bộ 'foo' đã tồn tại. Xin lỗi, nhưng tôi không thể trả lời tại sao điều này xảy ra. – Mischa

+0

Tôi cũng không thể trả lời tại sao. Nhưng nếu có sự mơ hồ giữa các biến và phương thức cục bộ, hãy đảm bảo sử dụng 'self.foo' cho phương thức và' foo' cho biến. –

+0

@sawa - Tôi sẽ không quay lại lần nữa, nhưng tôi không hiểu nhận xét của bạn và tôi không hiểu tại sao bạn thay đổi câu hỏi của bmesuere. Không có gì sai với câu hỏi. Tôi không thấy cần chỉnh sửa nó. – Mischa

Trả lời

5

Tên ở phía bên trái của bài tập được đặt thành nil, ngay cả khi không thể truy cập mã như trong trường hợp if false.

>> foo 
NameError: undefined local variable or method `foo' for main:Object 
... 
>> if false 
.. foo = 1 
.. end #=> nil 
>> foo #=> nil 

Khi Ruby cố gắng giải quyết barewords, nó lần đầu tiên trông cho biến cục bộ (có một tham chiếu đến đó trong cuốn sách Pickaxe, mà tôi dường như không thể tìm thấy ở thời điểm hiện tại). Vì bây giờ bạn có một cái gọi là foo, nó hiển thị nil. Như Mischa đã lưu ý, phương pháp vẫn có thể được gọi là foo().

+0

Nếu tôi hiểu rõ, biến 'foo' cục bộ được tạo trong khi ruby ​​phân tích mã, ngay cả khi mã đó có thể không bao giờ được thực hiện? – bmesuere

+2

Miễn là biến nằm ở phía bên tay trái của bài tập, vâng. BTW: vì bạn là người mới đối với SO, nghi thức ở đây là để upvote và/hoặc chấp nhận câu trả lời hữu ích. Nếu bạn có thêm câu hỏi, tôi vui mừng cập nhật câu trả lời của tôi. –

+0

Tôi xin lỗi, tôi đã không rõ ràng trong bình luận trước đây của tôi. Tôi có nghĩa là để hỏi nếu biến chỉ là "dành riêng" trong khi phân tích cú pháp, hoặc nếu bộ nhớ cũng được phân bổ (mà có vẻ khủng khiếp không hiệu quả)? – bmesuere

1

Đây là những gì bạn thân của tôi và Ruby siêu chuyên gia Josh Cheek đã phải nói:

Khi Ruby thấy nhiệm vụ, nó khởi tạo các biến trong phạm vi hiện tại và đặt nó vào nil. Kể từ khi nhiệm vụ đã không được chạy, nó đã không cập nhật giá trị của foo.

nếu câu lệnh không thay đổi phạm vi như các khối thực hiện. Đây cũng là sự khác biệt quan trọng nhất giữa

for x in xs 

xs.each { |x| } 

Dưới đây là một ví dụ khác:

a = 123 if a # => nil 
a # => nil 

Chúng ta không nên có thể nói if a bởi vì chúng tôi không bao giờ đặt a, nhưng Ruby thấy số a = 123 và khởi tạo a, sau đó truy cập if a tại thời điểm đó anil

Tôi cho rằng đó là sự giả mạo của trình thông dịch. Gary Bernhardt làm cho niềm vui của nó trong wat (https://www.destroyallsoftware.com/talks/wat) với a = a

-Josh

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