Y a-t-il une différence entre ::et .lors de l'appel de méthodes de classe dans Ruby ?
Question
Question simple, mais qui m'intéresse... y a-t-il une différence fonctionnelle entre les deux commandes suivantes ?
String::class
String.class
Ils font tous les deux ce que j'attends, c'est-à-dire qu'ils reviennent Class
-- mais quelle est la différence entre utiliser le ::
et le .
?
Je remarque que sur les classes pour lesquelles des constantes sont définies, la saisie semi-automatique d'IRB renverra les constantes comme options disponibles lorsque vous appuyez sur la tabulation après ::
mais pas après .
, mais je ne sais pas quelle en est la raison...
La solution
Le .
l'opérateur dit essentiellement "envoyer ce message à l'objet".Dans votre exemple, il appelle ce membre particulier.Le ::
L'opérateur "explore" jusqu'à la portée définie à gauche de l'opérateur, puis appelle le membre défini sur le côté droit de l'opérateur.
Quand vous utilisez ::
vous devez faire référence à des membres définis.Lors de l'utilisation .
vous envoyez simplement un message à l'objet.Ce message pouvant être n'importe quoi, la saisie semi-automatique ne fonctionne pas pour .
alors que c'est le cas pour ::
.
Autres conseils
En fait, la saisie semi-automatique fonctionne pour .
.Les options de complétion se trouvent en appelant #methods
sur l'objet.Vous pouvez le constater par vous-même en remplaçant Object.methods
:
>> def Object.methods; ["foo", "bar"]; end
=> nil
>> Object.[TAB]
Object.foo Object.bar
>> Object.
Notez que cela ne fonctionne que lorsque l'expression à gauche du .
est un littéral.Sinon, faire appeler l'objet #methods
cela impliquerait d’évaluer le côté gauche, ce qui pourrait avoir des effets secondaires.Vous pouvez également le constater par vous-même :
[continuing from above...]
>> def Object.baz; Object; end
=> nil
>> Object.baz.[TAB]
Display all 1022 possibilities? (y or n)
Nous ajoutons une méthode #baz
à Object
qui renvoie Object
lui-même.Ensuite, nous complétons automatiquement pour obtenir les méthodes sur lesquelles nous pouvons faire appel Object.baz
.Si la CISR appelle Object.baz.methods
, cela donnerait la même chose que Object.methods
.Au lieu de cela, l'IRB propose 1 022 suggestions.Je ne sais pas d'où ils viennent, mais il s'agit clairement d'une liste générique qui n'est pas réellement basée sur le contexte.
Le ::
L'opérateur est (également) utilisé pour obtenir les constantes d'un module, tandis que .
n'est pas.C'est pourquoi HTTP
apparaîtra dans l'achèvement pour Net::
, mais pas pour Net.
. Net.HTTP
ce n'est pas correct, mais Net::HTTP
est.