web-dev-qa-db-fra.com

Pourquoi l'expression (true == true == true) produit-elle une erreur de syntaxe?

Rubis:

true == true == true

erreur de syntaxe, tEQ inattendu

vs JavaScript:

true == true == true
// => true

vs C :

1 == 1 == 1
// => 1
65
Rrr Rrr

La direction d'association, qui contrôle l'ordre des opérateurs ayant leurs arguments évalués, n'est pas définie pour le == méthode, identique à ===, !=, =~ et <=> méthodes également (qui ont toutes la même priorité et forment exclusivement un groupe de priorité distinct).

Documentation

Ainsi, l'ordre d'évaluation dans le cas où plusieurs opérateurs de la liste mentionnée ci-dessus sont enchaînés doit être défini explicitement via

  • parenthèse ():

    (true == true) == true # => true
    true == (true == true) # => true
    
  • ou opérateur point . ( peut être omis pour la dernière vérification d'égalité consécutive):

    true .== true == true # => true
    
49
potashin

TL; DR La syntaxe implique que les 3 valeurs sont égales ce n'est pas ce qu'elle fait en javascript ou C, donc par Ruby donnant une erreur de syntaxe la porte est ouverte pour que cela soit implémenté dans le futur.

Si je comprends bien la question value_a == value_b == value_c ne doit retourner true que si elles sont toutes eqel en utilisant == comme opérateur de comparaison comme indiqué dans 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. pour mettre en œuvre cela 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 différents.

JavaScript utilise toujours la version 2, ce qui est assez inutile car le 3e élément est toujours comparé à vrai ou faux (0 ou 1 si le 3e élément est un entier) c'est pourquoi false == false == true renvoie vrai.

afin de garantir que si une méthode est l'une des trois valeurs qu'elle est appelée uniquement une fois que nous devons créer une copie (pas une référence) des trois variables, puis faire les comparaisons comme ceci:

def compare_3_values(a_original, b_original, c_original)
  #duplicate all three values as a, b, c
  a, b, c = a_original.dup, b_original.dup, c_original.dup

  a == b && b == c && a == c
end

La bonne nouvelle est que parce que Ruby donne une erreur de syntaxe, c'est le seul langage qui puisse l'implémenter sans casser le code de tout le monde.

pour tout autre langage, il casserait tellement de code que même s'il était implémenté dans une version majeure ultérieure, il faudrait un indicateur/paramètre pour l'activer ou le désactiver pour les années à venir, donc cela ne vaudra 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

Edit testé en C également, agit de manière similaire à JavaScript en ce qu'il compare le résultat des deux premières valeurs à la troisième valeur

6
Arye Eidelman

première réponse est excellent, mais juste au cas où ce ne serait pas complètement clair (et les gens demandent pourquoi), voici quelques exemples supplémentaires.


En C, le == L'opérateur est associatif de gauche à droite et le booléen est représenté par 1 (vrai) et 0 (faux), donc le premier 1 == 1 correspond à 1 (vrai), puis vous évaluez le résultat de la première expression avec la seconde. Tu peux essayer:

2 == 2 == 2 // => 0

Qui en C, est évalué comme:

(2 == 2) == 2
1 == 2 // => 0

En Javascript, de la même manière que C, == est associatif de gauche à droite. Essayons avec 0 cette fois (bien que le même exemple de C fonctionnerait aussi):

0 == 0 == 0
false

Encore:

0 == 0 == 0
true == 0 // => false

Dans Ruby == n'a pas de propriétés associatives, ie. il ne peut pas être utilisé plusieurs fois dans une seule expression, de sorte que cette expression ne peut pas être évaluée. Pourquoi cette décision a été prise est une question pour l'auteur de la langue. De plus, Ruby ne définit pas le numérique 1 comme un booléen, donc 1 == true est évalué à faux.

Le deuxième réponse indique qu'il y a des cas "étranges" dans Ruby, mais ils évaluent tous 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
4
Mayo