Differenza tra “e” e && in Ruby?


Risposte:


349

andè uguale &&ma con precedenza inferiore . Entrambi usano la valutazione del corto circuito .

ATTENZIONE: andha anche una precedenza inferiore rispetto a quella =che di solito vorrai evitare and. Un esempio di andutilizzo dovrebbe essere trovato nella Guida Rails in " Evitare errori di doppio rendering ".


50
Sarebbe una buona idea specificare che di solito si dovrebbe usare &&, mentre anddovrebbe essere usato solo per casi molto specifici.
Marc-André Lafortune,


17
Dal link di Andrew Marshall: "Un altro modo di pensare and è come un ifmodificatore di dichiarazione invertito : next if widget = widgets.popdiventa widget = widgets.pop and next. È un ottimo modo per dirlo, in realtà lo ha" fatto clic "nella mia testa (ed orè come un unlessmodificatore invertito ).
GMA

1
Combina questa risposta con i dettagli della risposta di Tadman e otterrai il quadro completo.
sargas,

5
Avdi ha aggiornato la sua opinione su quando usare e rispetto a &&. Fondamentalmente usa 'e' e 'o' per il flusso di controllo a causa della loro precedenza inferiore. devblog.avdi.org/2014/08/26/…
EricC

238

La differenza pratica è la forza vincolante, che può portare a comportamenti peculiari se non sei preparato per questo:

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 stessa cosa funziona per ||e or.


2
a = foo and bar e (a = foo ) && bar dimostra che andha una precedenza inferiore a &&.
sargas,

non capisco: cosa significa "foo and bar" per tornare?
BKSpurgeon,

a = foo and barè equivalente a (a = :foo) and nil. Poiché l'assegnazione restituisce un valore logicamente vero ( :foo), viene valutata la seconda parte, che non riesce, restituendo nil.
Tadman,

61

La Guida allo stile Ruby lo dice meglio di quanto potrei:

Usa && / || per espressioni booleane e / o per flusso di controllo. (Regola empirica: se devi usare parentesi esterne, stai usando gli operatori sbagliati.)

# boolean expression
if some_condition && some_other_condition
  do_something
end

# control flow
document.saved? or document.save!

53
In realtà la guida ora dice di evitare and/ orcompletamente, e potrebbero avere un punto. Spesso il loro utilizzo nel flusso di controllo potrebbe essere più ovviamente scritto con if/ unlessoperatori (ad es. document.save! unless document.saved?)
Yarin

@akostadinov nel caso tu non stia trollando: la guida di Ruby Style non è stata scritta dai creatori di Ruby. Ruby è stato creato da Yukihiro Matsumoto e altri, mentre la Ruby Style Guide è stata realizzata principalmente da Bozhidar Batsov.
Andrew Grimm,

2
@AndrewGrimm, grazie, buono a sapersi. Scusami per la pesca a traina ma sono sinceramente confuso con alcuni aspetti della realtà rubino. Una cosa è certa: ogni progetto ruby ​​ha bisogno di rigide politiche di stile per mantenere la base di codice mantenibile.
Akostadinov,

37

||e &&legare con la precedenza che ci si aspetta dagli operatori booleani nei linguaggi di programmazione ( &&è molto forte, ||è leggermente meno forte).

and e or hanno una precedenza inferiore.

Ad esempio, a differenza di ||, orha una precedenza inferiore a =:

> a = false || true
 => true 
> a
 => true 
> a = false or true
 => true 
> a
 => false

Allo stesso modo, a differenza &&, andha anche una precedenza inferiore rispetto a =:

> a = true && false
 => false 
> a
 => false 
> a = true and false
 => false 
> a
 => true 

Cosa c'è di più, a differenza di &&e ||, ande orlegare con uguale precedenza:

> !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

Il debolmente vincolante ande orpuò essere utile ai fini del flusso di controllo: vedi http://devblog.avdi.org/2010/08/02/using-and-and-or-in-ruby/ .


2
"a differenza ||, orha una precedenza inferiore rispetto a =" ... ora ha più senso, grazie!
Steph Sharp,

18

andha una precedenza inferiore a &&.

Ma per un utente senza pretese, potrebbero verificarsi problemi se viene utilizzato insieme ad altri operatori la cui precedenza è tra, ad esempio, l'operatore di assegnazione:

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

1
Grazie, ma in che modo la precedenza di "e" è diversa da "&&"?
BKSpurgeon,

2
@BKSpurgeon Vedi qui per un elenco ordinato di precedenza degli operatori in Ruby.
giovedì

5

andha una precedenza inferiore, principalmente lo usiamo come modificatore del flusso di controllo come if:

next if widget = widgets.pop

diventa

widget = widgets.pop and next

Per or:

raise "Not ready!" unless ready_to_rock?

diventa

ready_to_rock? or raise "Not ready!"

Preferisco usare ifma non and, perché ifè più intelligibile, quindi ignoro ande or.

Fare riferimento a " Utilizzo di" e "e" o "in Ruby " per ulteriori informazioni.


0

Non so se questa è l'intenzione di Ruby o se questo è un bug, ma prova questo codice qui sotto. Questo codice è stato eseguito su Ruby versione 2.5.1 ed era su un sistema Linux.

puts 1 > -1 and 257 < 256
# => false

puts 1 > -1 && 257 < 256
# => true

1
@JakubArnold Il sarcasmo non è mai utile. Gli esempi a volte lo sono.
BobRodes

@BobRodes Non è stato un sarcasmo. Ci sono 7 risposte, 6 delle quali hanno già degli esempi.
Jakub Arnold,

1
@JakubArnold Ho ancora trovato utile questo esempio.
BobRodes

Sto ottenendo anche risultati strani. v1 = true e false p v1 # => app.rb: true, IRB: false v2 = true && false p v2 # => app.rb: false, IRB: false inserisce 1> -1 && 257 <256 # => app.rb: false, IRB: false
Rich_F
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.