2008-09-04 6 views
24

Câu hỏi đơn giản, nhưng một câu hỏi mà tôi đã tò mò ... có sự khác biệt về chức năng giữa hai lệnh sau không?Có sự khác biệt nào giữa :: và. khi gọi các phương thức lớp trong Ruby?

String::class 
String.class 

Cả hai đều làm những gì tôi mong đợi - đó là để nói họ trở Class - nhưng sự khác biệt giữa việc sử dụng ::. là gì?

Tôi nhận thấy rằng trên những lớp có hằng số được xác định, tự động hoàn thành của IRB sẽ trả về hằng số dưới dạng tùy chọn có sẵn khi bạn nhấn tab sau :: nhưng không phải sau ., nhưng tôi không biết lý do là gì. ..

Trả lời

35

Nhà điều hành . về cơ bản nói "gửi thư này cho đối tượng". Trong ví dụ của bạn, nó đang kêu gọi một thành viên cụ thể. Toán tử :: "khoan" xuống phạm vi được xác định ở bên trái toán tử, sau đó gọi thành viên được xác định ở phía bên phải của toán tử.

Khi bạn sử dụng ::, bạn phải tham khảo các thành viên được xác định. Khi sử dụng ., bạn chỉ cần gửi tin nhắn đến đối tượng. Bởi vì thông điệp đó có thể là bất cứ điều gì, tự động hoàn thành không hoạt động cho . trong khi nó hoạt động cho ::.

11

Thực tế, tính năng tự động hoàn thành hoạt động cho .. Các tùy chọn hoàn thành được tìm thấy bằng cách gọi #methods trên đối tượng. Bạn có thể thấy điều này cho chính mình bằng cách ghi đè Object.methods:

>> def Object.methods; ["foo", "bar"]; end 
=> nil 
>> Object.[TAB] 
Object.foo Object.bar 
>> Object. 

Lưu ý rằng điều này chỉ hoạt động khi các biểu hiện bên trái của . là một chữ. Nếu không, việc nhận đối tượng gọi #methods sẽ liên quan đến việc đánh giá phía bên trái, có thể có tác dụng phụ. Bạn có thể thấy điều này cho chính mình cũng như:

[continuing from above...] 
>> def Object.baz; Object; end 
=> nil 
>> Object.baz.[TAB] 
Display all 1022 possibilities? (y or n) 

Chúng tôi thêm một phương pháp #baz-Object trả về Object riêng của mình. Sau đó, chúng tôi tự động hoàn tất để nhận các phương pháp mà chúng tôi có thể gọi vào số Object.baz. Nếu IRB gọi là Object.baz.methods, nó sẽ nhận được cùng một điều như Object.methods. Thay vào đó, IRB có 1022 gợi ý. Tôi không chắc họ đến từ đâu, nhưng rõ ràng là một danh sách chung chung không thực sự dựa trên ngữ cảnh.

Toán tử :: cũng được sử dụng để nhận các hằng số của mô-đun, trong khi . thì không. Đó là lý do tại sao HTTP sẽ hiển thị khi hoàn thành cho Net::, nhưng không hiển thị cho Net.. Net.HTTP không chính xác, nhưng Net::HTTP là.