Rubis :
true == true == true
erreur de syntaxe, tEQ inattendu
vs. JavaScript :
true == true == true
// => true
vs. C :
1 == 1 == 1
// => 1
Rubis :
true == true == true
erreur de syntaxe, tEQ inattendu
vs. JavaScript :
true == true == true
// => true
vs. C :
1 == 1 == 1
// => 1
La direction de l'association, qui contrôle l'ordre des opérateurs dont les arguments sont évalués, n'est pas définie pour l'élément ==
comme pour la méthode ===
, !=
, =~
y <=>
(qui ont toutes la même priorité et forment exclusivement un groupe de priorité distinct).
Ainsi, l'ordre d'évaluation dans le cas où plusieurs opérateurs de la liste mentionnée ci-dessus sont enchaînés dans une ligne doit être défini explicitement par l'intermédiaire de
parenthèse ()
:
(true == true) == true # => true
true == (true == true) # => true
ou opérateur point .
( peut être omis pour le dernier contrôle d'égalité d'une rangée ):
true .== true == true # => true
J'aimerais savoir pourquoi mais je pense que cela dépasse le cadre de la question et de votre réponse.
@CarySwoveland peut-être parce que 1 == 1 == 1
serait évaluée à false
en Ruby si ==
était associatif à gauche, ce qui entraînerait probablement plusieurs bogues. Et cela n'aurait pas beaucoup de sens non plus - les seules valeurs raisonnables pour le troisième opérande sont true
y false
, c'est-à-dire a == b == true
y a == b == false
qui peut être exprimée comme suit a == b
y a != b
.
@Stefan : il n'y a qu'une seule situation où l'on peut l'utiliser de cette manière et où cela aurait un sens, bien que je doive dire que l'exemple est un peu tiré par les cheveux : ==
peut être surchargée dans une classe personnalisée et le contrôle d'égalité peut donc renvoyer autre chose qu'un simple true
o false
(par exemple, nil
)
Si je comprends bien la question value_a == value_b == value_c
ne doit renvoyer true que si elles sont toutes égales en utilisant == comme opérateur de comparaison, comme le montre cette méthode
# version 1
def compare_3_values(a, b, c)
a == b && a == c && b == c
end
Il y a cependant un autre résultat attendu possible. pour le mettre en œuvre comme indiqué dans la réponse précédente :
#version 2
def compare_3_values(a, b, c)
(a == b) == c
end
Les résultats sont très différents.
JavaScript utilise toujours la version 2, ce qui est assez inutile car le troisième élément est toujours comparé à true ou false (0 ou 1 si le troisième élément est un entier), c'est pourquoi false == false == true
retourne à la réalité.
La bonne nouvelle, c'est que ruby donne une erreur de syntaxe et que c'est le seul langage qui peut implémenter cela sans casser le code de tout le monde.
pour tout autre langage, cela casserait tellement de code que même si cela était implémenté dans une version majeure ultérieure, il faudrait un drapeau/paramètre pour l'activer ou le désactiver pendant des années, ce qui n'en vaudrait jamais la peine.
Quelques résultats intéressants en Ruby
false .== false == true
=> true
false .== true == false
=> true
true .== false == false
=> true
false .== false == false
=> false
true .== true == false
false
Et en javascript
false == false == true
=> true
false == true == false
=> true
true == false == false
=> true
false == false == false
=> false
true == true == false
=> false
Editer testé en C également, agit de manière similaire à JavaScript en comparant le résultat des deux premières valeurs à la troisième valeur.
En première réponse est excellente, mais au cas où elle ne serait pas tout à fait claire (et où les gens se demanderaient pourquoi), voici quelques exemples supplémentaires.
En C, le ==
est associatif de gauche à droite et les booléens sont représentés par 1 (vrai) et 0 (faux). 1 == 1
s'évalue à 1
(vrai) et vous évaluez le résultat de la première expression avec la seconde. Vous pouvez essayer :
2 == 2 == 2 // => 0
Ce qui, en C, est évalué comme suit :
(2 == 2) == 2
1 == 2 // => 0
En Javascript, comme en C, ==
est associatif de gauche à droite. Essayons avec 0 cette fois-ci (bien que le même exemple de C fonctionnerait également) :
0 == 0 == 0
false
Encore une fois :
0 == 0 == 0
true == 0 // => false
En rubis ==
n'a pas de propriétés associatives, c'est-à-dire qu'il ne peut pas être utilisé plusieurs fois dans une même expression, de sorte que cette expression ne peut pas être évaluée. La raison pour laquelle cette décision a été prise est une question pour l'auteur du langage. De plus, Ruby ne définit pas le chiffre 1 comme un booléen, donc 1 == true
est évaluée à false.
En deuxième réponse indique qu'il existe des cas "bizarres" en Ruby, mais qu'ils sont tous évalués comme prévu :
(1 == 1) == 1
true == 1 # => false
1 == (1 == 1)
1 == true # => false
1 .== 1 == 1
(1 == 1) == 1
true == 1 # => false
false .== false == true
(false == false) == true
true == true # => true
false .== true == false
(false == true) == false
false == false # => true
true .== false == false
(true == false) == false
false == false # => true
false .== false == false
(false == false) == false
true == false # => false
true .== true == false
(true == true) == false
true == false # => false
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.
2 votes
Ce qui est intéressant, c'est que seuls les opérateurs d'égalité (
==
,===
y!=
) qui le font. Même les<
y>
s'analyse correctement et produit ensuite une erreur d'exécution, comme vous vous y attendez. De plus, le seulement sources Je n'ai trouvé aucune grammaire complète pour Ruby, ce qui semble indiquer que cette syntaxe est autorisée.2 votes
Il fonctionne également sans parenthèses comme ceci, avec un appel explicite,
true .== true .== true
4 votes
Je me demande combien d'autres personnes ont tapé avec incrédulité le code défaillant dans l'irb en s'attendant à un résultat différent.
0 votes
stackoverflow.com/a/21060235/2864740 -
==
est répertorié comme non associatif (A=N) dans la réponse, ce qui signifie qu'un telX==Y==Z
est invalide (l'associativité est ce qui "ajoute la parenthèse implicite autour des opérateurs de même précédence"). Il y a de nombreux liens dans la question qui pourraient renvoyer à une "source officielle" qui pourrait être citée proprement. (Cette question porte plus ou moins sur un sous-ensemble/une application spécifique des règles de grammaire dans cette question/réponse).0 votes
@SilvioMayolo Selon la réponse ci-dessus,
<
et ses amis sont associatif à gauche donc devrait s'analyser (et "fonctionner", étant donné des entrées d'exécution valides). Je ne suis pas sûr de ce que la grammaire rationnelle à propos de pourquoi<
serait associative alors que==
ne le serait pas, bien que changer cela pourrait briser beaucoup d'attentes0 votes
Nous savons donc qu'il s'agit d'un comportement voulu, comme l'indique le lien fourni. Il ne reste plus qu'à savoir pourquoi. Je ne vois pas de raison de faire de
==
non associatif, mais qui laisse<
et la société sont associatives.0 votes
@SilvioMayolo Le "pourquoi" de la grammaire est souvent hors sujet :) Cependant, un exemple pratique de syntaxe qui fonctionne alors qu'il ne fonctionnerait pas s'il y avait de l'associativité (c'est-à-dire que la non-associativité permet ceci autres (en supprimant toute autre ambiguïté) serait intéressante à voir.