2008-09-04 6 views
24

Einfache Frage, aber eine, auf die ich neugierig war ... gibt es einen funktionalen Unterschied zwischen den folgenden beiden Befehlen?Gibt es einen Unterschied zwischen :: und? beim Aufruf von Klassenmethoden in Ruby?

String::class 
String.class 

Sie beide tun, was ich erwarten - das heißt, sie Class zurückkehren sagen - aber was ist der Unterschied zwischen den :: verwenden und die .?

Ich stelle fest, auf diesen Klassen, dass die Konstanten definiert, IRB Auto-Vervollständigung haben die Konstanten als verfügbaren Optionen zurück, wenn Sie mit der Tabulatortaste nach :: drücken, aber nicht nach ., aber ich weiß nicht, was der Grund dafür ist. ..

Antwort

35

Der Operator . sagt grundsätzlich "diese Nachricht an das Objekt senden". In Ihrem Beispiel ruft es dieses bestimmte Mitglied auf. Der Operator :: "bohrt" sich zu dem Bereich, der auf der linken Seite des Bedieners definiert ist, und ruft dann das auf der rechten Seite des Bedieners definierte Element auf.

Wenn Sie :: verwenden, müssen Sie sich auf Mitglieder beziehen, die definiert sind. Wenn Sie . verwenden, senden Sie einfach eine Nachricht an das Objekt. Da diese Nachricht alles sein kann, funktioniert die automatische Vervollständigung nicht für ., während sie für :: funktioniert.

11

Eigentlich funktioniert Auto-Vervollständigung für .. Die Beendigungsoptionen werden gefunden, indem #methods für das Objekt aufgerufen wird. Sie können diese Object.methods durch zwingende selbst sehen:

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

Beachten Sie, dass dies nur funktioniert, wenn der Ausdruck auf der linken Seite des . eine wörtliche ist. Andernfalls würde das Abrufen des Objekts, das #methods aufrufen soll, die Auswertung der linken Seite beinhalten, was zu Nebenwirkungen führen kann. Sie können für sich selbst als auch sehen:

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

wir eine Methode #baz-Object hinzufügen, die Object selbst zurückgibt. Dann vervollständigen wir automatisch die Methoden, die wir unter Object.baz aufrufen können. Wenn IRB Object.baz.methods aufgerufen wird, würde es dasselbe wie Object.methods erhalten. Stattdessen hat IRB 1022 Vorschläge. Ich bin mir nicht sicher, woher sie kommen, aber es ist eindeutig eine generische Liste, die nicht wirklich auf Kontext basiert.

Der Operator :: wird (auch) zum Abrufen der Konstanten eines Moduls verwendet, während . nicht verwendet wird. Deshalb erscheint HTTP in der Fertigstellung für Net::, aber nicht für Net.. Net.HTTP ist nicht korrekt, aber Net::HTTP ist.

Verwandte Themen