2008-09-04 72 views
24

簡單的問題,但我一直很好奇......是否有以下兩個命令之間的功能差異?::和之間有區別嗎?在Ruby中調用類方法時?

String::class 
String.class 

他們都做什麼,我期待的 - 也就是說,他們返回Class - 但就是使用::.之間的區別?

我注意到,在那些定義了常量的類上,當你在::之後按Tab鍵時,IRB的自動完成將返回常量作爲可用選項,但我不知道這是什麼原因。 ..

回答

35

.運營商基本上說「發送此消息到對象」。在你的例子中,它正在調用該特定成員。 ::運算符「向下鑽取」到在運算符左側定義的範圍,然後調用運算符右側定義的成員。當您使用::時,您必須引用已定義的成員。使用.時,您只需向對象發送消息。由於該消息可能是任何內容,因此自動完成對.不起作用,而對於::則自動完成不起作用。

11

實際上,自動完成對.有效。完成選項可通過在對象上調用#methods找到。您可以通過覆蓋Object.methods看到自己:

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

注意,當表達了.的左邊是一個文字這僅適用。否則,讓對象調用#methods將涉及評估左側,這可能會有副作用。您可以也看到自己這一點:

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

我們添加一個方法來#baz其中Object返回Object本身。然後我們自動完成以獲取我們可以撥打的方法Object.baz。如果IRB調用Object.baz.methods,它會得到與Object.methods相同的結果。相反,IRB有1022條建議。我不確定它們來自哪裏,但它顯然是一個通用的列表,實際上並不基於上下文。

::運算符(也)用於獲取模塊的常量,而.不是。這就是爲什麼HTTP將出現在Net::的完成中,而不是Net.Net.HTTP是不正確的,但Net::HTTP是。

相關問題