Quelle est la différence entre l'égalité?, eql?, = = = et ==?
Je suis en train d'essayer de comprendre la différence entre ces quatre méthodes. Je sais par défaut que ==
appelle la méthode equal?
qui renvoie vrai si les deux opérandes reportez-vous à exactement le même objet.
===
par défaut des appels ==
qui appelle equal?
... bon, donc, si l'ensemble de ces trois méthodes ne sont pas remplacées, alors je suppose
===
, ==
et equal?
faire exactement la même chose?
Vient maintenant eql?
. Qu'est-ce faire (par défaut)? Faut-il faire un appel à l'opérande de hachage de l'/id?
Pourquoi Ruby ont donc beaucoup de l'égalité des signes? Sont-ils censés diffèrent dans la sémantique?
- Je viens de commencer une cisr et a le résultat suivant qui est en contradiction avec les vôtres...l'Ensemble de ces 3 sont remplies:
"a" == "a"
,"a" === "a"
et"a".eql? "a"
. Mais c'est faux:"a".equal? "a"
(le Mien est ruby 1.9.2-p180) - C'est parce que les chaînes de remplacer tous les opérateurs d'égalité. Essayez d'utiliser
a = Object.new; b = Object.new
puis tous les==
,===
,.equal?
,.eql?
sera de retourtrue
poura
vsa
et false poura
vsb
.
Vous devez vous connecter pour publier un commentaire.
Je vais fortement citation l'Objet de la documentation ici, parce que je pense qu'il a quelques grandes explications. Je vous encourage à le lire, et aussi à la documentation de ces méthodes car elles sont remplacées dans d'autres classes, comme Chaîne.
Côté remarque: si vous voulez les essayer pour vous-même sur des objets différents, utiliser quelque chose comme ceci:
==
— générique de "l'égalité"C'est le plus commun de comparaison, et donc les plus fondamentales de l'endroit où vous (en tant qu'auteur d'une classe) de décider si deux objets sont "égaux" ou pas.
===
cas d'égalitéC'est incroyablement utile. Des exemples de choses qui sont intéressantes
===
implémentations:De sorte que vous pouvez faire des choses comme:
Voir ma réponse ici pour un exemple clair de la façon dont
case
+Regex
peut rendre le code beaucoup plus propre. Et bien sûr, en fournissant votre propre===
mise en œuvre, vous pouvez obtenir personnalisécase
sémantique.eql?
—Hash
l'égalitéVous êtes donc libre de remplacer cette valeur pour votre propre usage, ou vous pouvez remplacer
==
et l'utilisationalias :eql? :==
donc, les deux méthodes se comportent de la même manière.equal?
— identité comparaisonC'est effectivement le pointeur de la comparaison.
Numeric
poignées dans le plus strict, que==
. C'est vraiment à l'auteur de la classe.===
est rarement utilisé en dehors decase
consolidés.===
le sens de "matchs" (à peu près). Comme dans "la regexp correspondre à la chaîne" ou "la gamme de match (notamment) le nombre".===
estClass
; il fonctionne de manière similaire àis_a?
. C'est pourquoi vous pouvez faire:case obj; when String; :string; when Array; :array end
eql?
devrait être appelé "hachage de l'égalité", car il est utilisé lors de la vérification que les clés de Hachage sont les mêmes. C'est pourquoi{1=>true, 1.0=>true}.size == 2
et[1, 1.0].size == 2
. À partir de l'Objet documention: "La eql? la méthode retourne true si l'obj et d'autres se réfèrent à la même clé de hachage."[1, 1.0].uniq.size == 2
===
. wellho.net/mouth/985_Equality-in-Ruby-eql-and-equal-.htmluniq
etc. de travail. Ce ne devrait pas être nécessaire -- les docs pour l'objet.c dire "Le <code>eql?</code> méthode de retour <code>true</code> si +obj+ et +autre+ référer à la même clé de hachage." -- mais, apparemment, de la classe de base n'est pas tout à fait, plutôt qu'une simple comparaison de pointeurs d'objet -- voir github.com/ruby/ruby/edit/trunk/object.c#L205J'aime jtbandes réponse, mais comme il est assez long, je vais ajouter mes propres compact réponse:
==
,===
,eql?
,equal?
4 comparateurs, c'est à dire. 4 façons de comparer 2 objets, en Ruby.
Comme, en Ruby, tous les comparateurs de (et la plupart des opérateurs) sont en fait la méthode des appels, vous pouvez modifier, remplacer, et de définir la sémantique de ces la comparaison des méthodes vous-même. Cependant, il est important de comprendre, quand Ruby interne de constructions d'un langage de l'utilisation qui comparateur:
==
(comparaison de la valeur)Ruby utilise :== partout pour comparer les valeurs de 2 objets, par exemple. Hachage-valeurs:
===
(cas de comparaison)Ruby utilise :=== dans le cas où/quand constructions. Les extraits de code suivants sont logiquement identiques:
eql?
(De hachage de la comparaison clé)Ruby utilise :eql? (en combinaison avec la méthode de hachage) pour comparer les Mot-clés. Dans la plupart des classes :eql? est identique :==.
Les connaissances sur :eql? n'est important, lorsque vous souhaitez créer vos propres classes spéciales:
Remarque: Le couramment utilisées Ruby classe et s'appuie également sur le Hachage de clé de comparaison.
equal?
(l'identité de l'objet de comparaison)Ruby utilise :l'égalité? pour vérifier si deux objets sont identiques. Cette méthode (de la classe BasicObject) n'est pas censé être remplacé.
eql?
est très trompeur.eql?
est une comparaison d'égalité qui est compatible comment hash est calculé, c'est à direa.eql?(b)
garantit quea.hash == b.hash
. Il n' pas, il suffit de comparer les codes de hachage.Opérateurs d'égalité: == et !=
L'opérateur==, aussi connu comme l'égalité ou la double égalité, renvoie true si les deux objets sont égaux, et false si ils ne le sont pas.
L' != l'opérateur, aussi connu comme l'inégalité, est à l'opposé de ==. Elle renvoie true si les deux objets ne sont pas égaux, et false si elles sont égales.
Noter que les deux tableaux, avec les mêmes éléments dans un ordre différent ne sont pas égaux, les majuscules et les minuscules versions de la même lettre ne sont pas égaux et ainsi de suite.
Lorsque l'on compare les nombres de types différents (par exemple, entiers et à virgule flottante), si leur valeur numérique est la même chose, == retourne true.
l'égalité?
À la différence de l'opérateur == qui teste si les deux opérandes sont de valeur égale, l'égalité de méthode vérifie si les deux opérandes font référence au même objet. C'est la forme la plus stricte de l'égalité en Ruby.
Exemple:
a = "zen"
b = "zen"
Dans l'exemple ci-dessus, nous avons deux chaînes de caractères avec la même valeur. Cependant, ils sont deux objets distincts, avec différents Identifiants d'objets. Par conséquent, l'égalité? méthode renvoie false.
Nous allons essayer de nouveau, mais cette fois-b sera une référence à un. Notez que l'ID de l'objet est le même pour les deux variables, car elles pointent vers le même objet.
eql?
Dans la classe Hash, le eql? méthode il est utilisé pour tester des clefs pour l'égalité. Un peu de fond est nécessaire pour expliquer cela. Dans le contexte général de l'informatique, une fonction de hachage prend une chaîne de caractères (ou un fichier) de toute taille et génère une chaîne ou un entier de taille fixe appelés hashcode, communément appelé seulement de hachage. Couramment utilisé hashcode types sont MD5, SHA-1, et le CRC. Ils sont utilisés dans les algorithmes de chiffrement, indexation de bases de données, fichier de vérification de l'intégrité, etc. Certains langages de programmation, comme le Rubis, de fournir un type de collection appelée table de hachage. Les tables de hachage sont de type dictionnaire des collections qui stockent des données dans des paires, composé de clés uniques et leurs valeurs correspondantes. Sous le capot, ces clés sont stockées en tant que hashcodes. Les tables de hachage sont communément appelés les tables de hachage. Remarquez comment le mot hashcan se référer à un hashcode ou à une table de hachage. Dans le contexte de programmation Ruby, le mot de hachage renvoie presque toujours à un dictionnaire comme collection.
Ruby fournit une méthode intégrée appelé hash pour générer des codes hachés. Dans l'exemple ci-dessous, il prend une chaîne de caractères et renvoie un hashcode. Remarquez comment les chaînes avec la même valeur de toujours avoir le même hashcode, même si elles sont des objets distincts (avec différents Identifiants d'objets).
La méthode de hachage est mis en œuvre dans le module du Noyau, inclus dans la classe de l'Objet, qui est la valeur par défaut de la racine de tous les objets Ruby. Certaines classes comme le Symbole Entier et utiliser la valeur par défaut de mise en œuvre, d'autres, comme la Chaîne de Hachage et de fournir leurs propres implémentations.
En Ruby, lorsque nous stockons quelque chose dans une table de hachage (collection), l'objet fourni en tant que clé (par exemple, une chaîne ou un symbole) est convertie et stockée comme un hashcode. Plus tard, lors de la récupération d'un élément de la table de hachage (collection), nous fournissons un objet comme une clé, qui est converti en un hashcode et par rapport à l'existant clés. Si il y a une correspondance, la valeur de l'élément correspondant est retourné. La comparaison est faite à l'aide de la eql? méthode sous le capot.
Dans la plupart des cas, la eql? la méthode se comporte de façon similaire à l' == méthode. Cependant, il existe quelques exceptions. Par exemple, eql? n'effectue pas de conversion de type implicite lors de la comparaison d'un nombre entier à un flotteur.
Cas opérateur d'égalité: ===
Beaucoup de Ruby sont intégrés dans les classes, tels que la Chaîne, la Portée et la Regexp, fournir leurs propres implémentations de l' === opérateur, aussi connu comme cas d'égalité, le triple est égal ou threequals. Parce qu'il est mis en œuvre différemment dans chaque classe, il va se comporter différemment selon le type d'objet, il a été appelé. Généralement, elle renvoie true si l'objet sur la droite "appartient à" ou "est un membre de" l'objet sur la gauche. Par exemple, il peut être utilisé pour tester si un objet est une instance d'une classe (ou un de ses sous-classes).
Le même résultat peut être obtenu avec d'autres méthodes qui sont probablement les mieux adaptés pour le travail. Il est généralement préférable d'écrire du code qui est facile à lire par être aussi explicite que possible, sans sacrifier l'efficacité et la concision.
Avis le dernier exemple retourné false parce que des entiers tels que les 2 sont des instances de la Fixnum classe, qui est une sous-classe de la classe Integer. L' ===, is_a? et instance_of? méthodes renvoie true si l'objet est une instance de la classe donnée ou toutes les sous-classes. Le instance_of méthode est plus stricte et ne retourne true si l'objet est une instance de la même classe, pas une sous-classe.
La is_a? et kind_of? les méthodes sont implémentées dans le module du Noyau, qui est mélangé par la classe de l'Objet. Les deux sont des alias à la même méthode. Nous allons vérifier:
Noyau.instance_method(:kind_of?) == Noyau.instance_method(:is_a?) # Sortie: => true
Gamme de mise en Œuvre de l' ===
Lorsque l' === opérateur est appelée sur un objet de la plage, elle renvoie true si la valeur sur la droite se situe dans la plage sur la gauche.
Rappelez-vous que l' === opérateur invoque l' === méthode de la gauche de l'objet. Donc (1..4) === 3 est équivalent à (1..4).=== 3. En d'autres termes, la classe de la gauche opérande permettra de définir la mise en œuvre de l' === méthode sera appelée, si l'opérande de postes ne sont pas interchangeables.
Regexp mise en Œuvre de l' ===
Retourne true si la chaîne sur la droite correspond à l'expression régulière sur la gauche.
/zen/=== "la pratique de zazen aujourd'hui" # Sortie: => true
# est le même que
"la pratique de zazen aujourd'hui"=~ /zen/
Implicite de l'utilisation de l' === opérateur de cas/quand consolidés
Cet opérateur est également utilisé sous le capot de cas/quand consolidés. C'est son usage le plus courant.
Dans l'exemple ci-dessus, si Ruby avait implicitement utilisé le double opérateur égal (==), la gamme 10..20 ne serait pas considérée comme égale à un nombre entier, par exemple 15. Ils correspondent à cause de la triple opérateur égal (===) est implicitement utilisée dans tous les cas/quand consolidés. Le code dans l'exemple ci-dessus est équivalente à:
Pattern matching opérateurs: =~ et !~
L' =~ (égale-tilde) et !~ (bang-tilde) les opérateurs sont utilisés pour faire correspondre les chaînes de caractères et des symboles à l'encontre de modèles regex.
La mise en œuvre de l' =~ méthode dans la Chaîne et le Symbole des classes s'attend à une expression régulière (une instance de la classe Regexp) comme argument.
La mise en œuvre dans la classe Regexp attend une chaîne ou d'un symbole comme un argument.
Dans toutes les implémentations, lorsque la chaîne ou le symbole correspond à l'expression régulière pattern, elle renvoie un entier qui correspond à la position (index) de la correspondance. Si aucune correspondance n'est trouvée, elle renvoie nil. Rappelez-vous que, en Ruby, n'importe quelle valeur entière est "truthy" et de néant est "falsy", de sorte que l' =~ opérateur peut être utilisé dans les instructions if et ternaires opérateurs.
"Pattern-matching" les opérateurs sont également utiles pour l'écriture de courts si les déclarations. Exemple:
L' !~ l'opérateur est à l'opposé de =~, elle renvoie true quand il n'y a pas de match, et false si il y a un match.
Plus d'infos sont disponibles sur ce blog.
:zen === "zen"
retourne falsea.eql?(b)
est le même quea.hash == b.hash
est faux.a.eql?(b)
impliquea.hash == b.hash
, mais l'inverse n'est pas vrai: des codes de hachage peut correspondre, même quand les objets ne sont paseql?
.=== #---cas d'égalité
== #--- générique de l'égalité
les deux œuvres similaires, mais "===" même le faire affaire états
ici la différence
a==b
puisa===b
. Maisa===b
est beaucoup plus puissant.===
n'est pas symétrique, eta===b
signifie une chose très différente deb===a
, sans parler dea==b
.Je voudrais élargir le
===
opérateur.===
n'est pas un opérateur d'égalité!Pas.
Let's get ce point, vraiment partout.
Vous pourriez être familier avec
===
comme un opérateur d'égalité en Javascript et en PHP, mais ce tout simplement pas un opérateur d'égalité en Ruby et a fondamentalement différent de la sémantique.Donc, ce n'est
===
faire?===
est le filtrage de l'opérateur!===
correspond à des expressions régulières===
vérifie adhésion plage===
vérifie instance d'une classe===
appelle les expressions lambda===
parfois vérifie l'égalité, mais la plupart du temps, il n'a pasAlors, comment est-ce de la folie de sens?
Enumerable#grep
utilise===
en internecase when
consolidés===
en internerescue
utilise===
en interneC'est pourquoi vous pouvez utiliser des expressions régulières et des classes et des plages et même des expressions lambda dans un
case when
déclaration.Quelques exemples
Tous ces exemple travailler avec
pattern === value
trop, ainsi qu'avecgrep
méthode.Ruby expose les différentes méthodes pour le traitement de l'égalité:
Continuer la lecture en cliquant sur le lien ci-dessous, il m'a donné un clair résumé de la compréhension.
Espère que cela aide les autres.
J'ai écrit un test simple pour tous les ci-dessus.