Il peut avoir 3 significations distinctes :
'<<' comme une méthode ordinaire
Dans la plupart des cas, '<<' est une méthode définie comme les autres, dans votre cas, cela signifie "ajouter à la fin de ce tableau" (voir aussi aquí ).
C'est dans votre cas particulier, mais il y a aussi beaucoup d'autres occasions où vous rencontrerez la méthode "<<". Je ne l'appellerai pas 'opérateur' puisqu'il s'agit en réalité d'une méthode définie sur un objet qui peut être surchargée par vous ou implémentée pour vos propres objets. Autres cas de "<<
- Concaténation de chaînes de caractères : "a" << "b"
- Écriture de la sortie vers un IO : io << "Une ligne de texte". \n "
- Écriture de données dans un condensé de message, un HMAC ou un chiffrement : sha << "Texte à hacher"
- décalage à gauche d'un OpenSSL::BN : bn << 2
- ...
Définition de la classe singleton
Ensuite, il y a le mystérieux déplacement de la portée actuelle (= changement de soi) dans le déroulement du programme :
class A
class << self
puts self # self is the singleton class of A
end
end
a = A.new
class << a
puts self # now it's the singleton class of object a
end
Le mystère class << self
m'a fait m'interroger et enquêter sur les internes. Alors que dans tous les exemples que j'ai mentionnés <<
est en réalité une méthode définie dans une classe, à savoir
obj << stuff
est équivalent à
obj.<<(stuff)
le site class << self
(ou tout autre objet à la place du soi) la construction est vraiment différente. Il s'agit d'une fonctionnalité intégrée au langage lui-même, dans CRuby, elle est définie dans la section parse.y comme
k_class tLSHFT expr
k_class
est le mot-clé "classe", où tLSHFT
est un jeton '<<' et expr
est une expression arbitraire. C'est-à-dire que vous pouvez réellement écrire
class << <any expression>
et obtiendra décalé dans la classe singleton du résultat de l'expression. Le site tLSHFT
sera analysée en tant qu'expression 'NODE_SCLASS', qui est appelée un Définition de la classe Singleton (cf. node.c)
case NODE_SCLASS:
ANN("singleton class definition");
ANN("format: class << [nd_recv]; [nd_body]; end");
ANN("example: class << obj; ..; end");
F_NODE(nd_recv, "receiver");
LAST_NODE;
F_NODE(nd_body, "singleton class definition");
break;
Documents ici
Documents ici utiliser "<<" d'une manière qui est encore une fois totalement différente. Vous pouvez définir une chaîne de caractères qui s'étend sur plusieurs lignes de manière pratique en déclarant
here_doc = <<_EOS_
The quick brown fox jumps over the lazy dog.
...
_EOS_
Pour distinguer l'opérateur "here doc", un délimiteur de chaîne arbitraire doit suivre immédiatement le "<<". Tout ce qui se trouve entre ce délimiteur initial et la deuxième occurrence de ce même délimiteur fera partie de la chaîne finale. Il est également possible d'utiliser '<<-', la différence étant que l'utilisation de ce dernier ignorera tout espace en tête ou en queue de chaîne.