Quelle est la différence entre les opérateurs &&
et and
dans Ruby?
and
est identique à &&
mais avec préséance inférieure . Ils utilisent tous les deux évaluation de court-circuit .
AVERTISSEMENT: and
a même une priorité inférieure à =
donc vous voudrez généralement éviter and
. Vous trouverez un exemple d'utilisation de and
dans le Rails Guide: https://guides.rubyonrails.org/layouts_and_rendering.html#avoiding-double-render-errors).
La différence pratique réside dans la force de la liaison, ce qui peut conduire à un comportement particulier si vous n’êtes pas préparé à cela:
foo = :foo
bar = nil
a = foo and bar
# => nil
a
# => :foo
a = foo && bar
# => nil
a
# => nil
a = (foo and bar)
# => nil
a
# => nil
(a = foo) && bar
# => nil
a
# => :foo
La même chose fonctionne pour ||
et or
.
Le Ruby Style Guide le dit mieux que je ne pourrais le faire:
Utilisez &&/|| pour les expressions booléennes et/ou pour le flux de contrôle. (Règle générale: si vous devez utiliser des parenthèses externes, vous utilisez les mauvais opérateurs.)
# boolean expression
if some_condition && some_other_condition
do_something
end
# control flow
document.saved? or document.save!
||
et &&
sont liés à la priorité que vous attendez des opérateurs booléens dans les langages de programmation (&&
est très fort, ||
est légèrement moins fort).
and
et or
ont une priorité inférieure.
Par exemple, contrairement à ||
, or
a une priorité inférieure à =
:
> a = false || true
=> true
> a
=> true
> a = false or true
=> true
> a
=> false
De même, contrairement à &&
, and
a également une priorité inférieure à celle de =
:
> a = true && false
=> false
> a
=> false
> a = true and false
=> false
> a
=> true
De plus, contrairement à &&
et ||
, and
et or
, la liaison est identique.
> !puts(1) || !puts(2) && !puts(3)
1
=> true
> !puts(1) or !puts(2) and !puts(3)
1
3
=> true
> !puts(1) or (!puts(2) and !puts(3))
1
=> true
Les variables and
et or
faiblement contraignantes peuvent être utiles à des fins de contrôle: voir http://devblog.avdi.org/2010/08/02/using-and-and -or-in-Ruby / .
and
a une priorité inférieure à &&
.
Mais pour un utilisateur sans prétention, des problèmes peuvent survenir s'il est utilisé avec d'autres opérateurs dont la priorité est intermédiaire, par exemple l'opérateur d'affectation.
par exemple
def happy?() true; end
def know_it?() true; end
todo = happy? && know_it? ? "Clap your hands" : "Do Nothing"
todo
# => "Clap your hands"
todo = happy? and know_it? ? "Clap your hands" : "Do Nothing"
todo
# => true
et ont une priorité inférieure, nous l'utilisons généralement comme modificateur de flux de contrôle tel que if
next if widget = widgets.pop
devient
widget = widgets.pop and next
pour ou
raise "Not ready!" unless ready_to_rock?
devient
ready_to_rock? or raise "Not ready!"
Je préfère utiliser si mais pas et , car si est plus intelligible, donc j'ignore simplement et et ou .
Référence à
Je ne sais pas si c'est Ruby intention ou s'il s'agit d'un bogue, mais essayez ce code ci-dessous. Ce code a été exécuté sur Ruby version 2.5.1 et était sur un système Linux.
puts 1 > -1 and 257 < 256
# => false
puts 1 > -1 && 257 < 256
# => true