Quelle est la différence entre les opérateurs or
et ||
dans Ruby? Ou est-ce juste une préférence?Différence entre "ou" et || dans Ruby?
Répondre
C'est une question de priorité des opérateurs.
||
a une priorité supérieure à or
. Donc, entre les deux vous avez d'autres opérateurs, y compris ternaire (? :
) et l'affectation (=
) de sorte que celui que vous choisissez peut affecter le résultat des déclarations. Il s'agit d'un ruby operator precedence table. Voir this question pour un autre exemple en utilisant and
/&&
.
Aussi, soyez au courant de certaines choses désagréables qui pourraient se produire:
a = false || true
=> true
a
=> true
a = false or true
=> true
a
=> false
deux des deux précédentes déclarations évaluent à true
, mais le second ensembles a
à false
depuis =
priorité est inférieure à ||
mais supérieur or
.
Le deuxième exemple est incorrect. 'a = false ou true' n'évalue pas' false'. – cdosborn
@cdosborn alors qu'il évalue à 'true',' a' est assigné 'false' dans l'expression, et ceci est aussi non intuitif. –
Juste pour ajouter à la réponse de mopoke, c'est aussi une question de sémantique. or
est considéré comme une bonne pratique car il se lit beaucoup mieux que ||
.
Je ne sais pas si "bonne pratique" est du côté de l'opérateur ou. Le cas est analogue aux arguments parens sur. Les appels de méthode sont souvent lus plus agréablement sans, mais dans certains cas, ils provoquent des bogues étranges. J'avais l'habitude d'utiliser ou de laisser tomber les parens, mais finalement je les ai abandonnés car assez souvent ils ne pouvaient pas être utilisés, certains de ces moments j'ai oublié et introduit un bug, et je suis venu à préférer la cohérence de toujours utiliser parens et ||. La situation est au moins discutable. – tfwright
vous voulez dire que c'est une question de syntaxe :) ils ont tous les deux la même interprétation sémantique (priorité d'opérateur modulo) – klochner
Si vous comptez sur la précédence pour l'arithmétique booléenne, alors votre code n'est pas lisible de toute façon. Ajoutez des parenthèses ou un refactor. –
Comme les autres l'ont déjà expliqué, la différence seule est la priorité. Cependant, je voudrais souligner qu'il ya effectivement deux différences entre les deux:
and
,or
etnot
ont beaucoup moins prioritaire que&&
,||
et!
and
etor
ont le même priorité, tandis que&&
a plus élevé précédence que||
En général, il est bon style pour éviter l'utilisation de and
, or
et not
et utiliser &&
, ||
et !
à la place. (Les développeurs core Rails, par exemple, rejettent les correctifs qui utilisent les formes de mot-clé au lieu des formulaires opérateur.)
La raison pour laquelle ils existent n'existe pas pour les formules booléennes mais pour le flux de contrôle. Ils ont fait leur chemin dans Ruby via l'idiome bien connu do_this or do_that
de Perl, où do_this
renvoie false
ou nil
s'il y a une erreur et seulement alors est exécuté do_that
à la place. (Analogue, il y a aussi l'idiome do_this and then_do_that
.)
Exemples:
download_file_via_fast_connection or download_via_slow_connection
download_latest_currency_rates and store_them_in_the_cache
Parfois, cela peut rendre le flux de contrôle un peu plus fluide que d'utiliser if
ou unless
.
Il est facile de voir pourquoi, dans ce cas, les opérateurs ont la «mauvaise» priorité (c'est-à-dire identique): ils n'apparaissent jamais ensemble dans la même expression. Et quand ils font apparaissent ensemble, vous veulent généralement eux d'être évalués simplement de gauche à droite.
Cela me fait parfois trébucher car en Perl, 'and' a une priorité supérieure à' or', reflétant '&&' et '||'. Mais d'habitude, vous ne devriez pas enchaîner de longues séries complexes de ces ensembles de toute façon. – ephemient
Intéressant, je ne le savais pas. Je n'ai jamais utilisé activement Perl, ni l'ai appris. –
Bonne réponse - Je ne savais pas à propos de la même chose de la préséance, ressemble à un accident qui attend de se produire. – klochner
ou N'est PAS la même chose que ||
Utilisez uniquement || opérateur au lieu de ou opérateur.
Raisons:
- ou opérateur ont priorité inférieure à ||
- ou ont priorité inférieur = opérateur d'affectation
- et et ou ont la même priorité, alors que & & a une priorité supérieure ||
"ou" et "||" évalue à vrai si l'un ou l'autre opérande est vrai. Ils évaluent leur deuxième opérande seulement si le premier est faux.
Comme avec "et", la seule différence entre "ou" et "||" est leur priorité. Pour rendre la vie intéressante, "et" et "ou" ont la même priorité, alors que "& &" a une priorité supérieure à "||".
Non. Ce n'est pas vrai. 'a = faux ou vrai', il y aura un' faux'. – Anwar
et/ou sont pour le flux de contrôle.
Ruby ne permettra pas à cette syntaxe comme valide:
false || raise "Error"
Cependant ceci est valable:
false or raise "Error"
Vous pouvez faire le premier travail, avec() mais en utilisant or
est la bonne méthode.
false || (raise "Error")
euh se demandant pourquoi cela a baissé. La deuxième réponse indique "la seule différence est la précédence" mais par mon exemple vous pouvez voir que ce n'est pas le cas. – Eadz
Cela semble en effet clairement démontrer que la réponse acceptée est (très légèrement) fausse. Est-ce que le comportement que vous démontrez ici est documenté n'importe où, à votre connaissance? –
Le fait que sa syntaxe soit invalide est une conséquence de la priorité de l'opérateur. raise ne revient pas à cet effet, il ne peut pas être évalué comme une expression. – bluehallu
La façon dont j'utilise ces opérateurs:
||, &&
sont pour la logique booléenne. or, and
sont pour le flux de contrôle. Par exemple.
do_smth if may_be || may_be
- nous évaluons la situation ici
do_smth or do_smth_else
- nous définissons le flux de travail, ce qui équivaut à do_smth_else unless do_smth
pour donner un exemple simple:
> puts "a" && "b" b
> puts 'a' and 'b' a
Un idiome bien connu dans Rails est render and return
. Il est un raccourci pour dire return if render
, alors que render && return
ne fonctionnera pas (voir Rails documentation)
puts false or true
impressions: faux
puts false || true
impressions: true
Yoda: Attention, vous devez être.
C'est si vous le faites passer à une méthode. En soi, il retourne toujours vrai –
Voir aussi [Différence entre 'and' et' && '] (http://stackoverflow.com/q/1426826/211563). –