2008-09-04 8 views
24

シンプルな質問ですが、私が好奇心を持っていたのは...次の2つのコマンドには機能的な違いがありますか? ::との間に違いがありますか? 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) 

我々はObject自身を返すObjectに方法#bazを追加します。次に、自動完成してObject.bazで呼び出すことのできるメソッドを取得します。 IRBがObject.baz.methodsと呼ばれる場合は、Object.methodsと同じことになります。代わりに、IRBには1022件の提案があります。私は彼らがどこから来たのかは分かりませんが、それは実際に文脈に基づいていない一般的なリストです。

::演算子は、モジュールの定数を取得するためにも使用されますが、.はそうではありません。だから、は、完了時にNet::に表示されますが、Net.は表示されません。 Net.HTTPは正しくありませんが、Net::HTTPはです。

関連する問題