¿Diferencia entre "y" y && en Ruby?

Respuestas:

349

andes lo mismo &&pero con menor precedencia . Ambos utilizan la evaluación de cortocircuito .

ADVERTENCIA: andincluso tiene una precedencia menor que la =que generalmente querrá evitar and. Se andpuede encontrar un ejemplo de cuándo se debe utilizar en la Guía de Rails en "Cómo evitar errores de doble representación ".

Dominic Rodger
fuente
50
Sería una buena idea especificar que generalmente se debe usar &&, mientras andque se debe usar solo para casos muy específicos.
Marc-André Lafortune
10
Otra buena explicación aquí: devblog.avdi.org/2010/08/02/using-and-and-or-in-ruby .
Andrew Marshall
17
Desde el enlace de Andrew Marshall: "Otra forma de pensar andes como un ifmodificador de declaración invertida : se next if widget = widgets.popconvierte widget = widgets.pop and next. Esa es una gran manera de decirlo, realmente lo hizo" hacer clic "en mi cabeza. (Y ores como un unlessmodificador invertido ).
GMA
1
Combine esta respuesta con los detalles de la respuesta de tadman y obtendrá la imagen completa.
sargas
55
Avdi actualizó su opinión sobre cuándo usar y vs. &&. Básicamente use 'y' y 'o' para el flujo de control debido a su precedencia más baja. devblog.avdi.org/2014/08/26/…
EricC
238

La diferencia práctica es la fuerza de unión, que puede conducir a un comportamiento peculiar si no está preparado para ello:

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

Lo mismo funciona para ||y or.

tadman
fuente
2
a = foo and bar y (a = foo ) && bar demuestra que andtiene menor prioridad que &&.
sargas
no lo entiendo: ¿qué significa "foo and bar" para regresar?
BKSpurgeon
a = foo and bares equivalente a (a = :foo) and nil. Dado que la asignación devuelve un valor lógicamente verdadero ( :foo), la segunda parte evalúa, que falla, regresando nil.
tadman
61

La Guía de estilo Ruby lo dice mejor de lo que podría:

Utilice && / || para expresiones booleanas y / o para flujo de control. (Regla de oro: si tiene que usar paréntesis externos, está usando los operadores incorrectos).

# boolean expression
if some_condition && some_other_condition
  do_something
end

# control flow
document.saved? or document.save!
Andrew Grimm
fuente
53
En realidad, la guía ahora dice evitar and/ orcompletamente, y podrían tener un punto. A menudo, su uso en el flujo de control podría escribirse más obviamente con if/ unlessoperadores de todos modos (por ejemplo document.save! unless document.saved?)
Yarin
@akostadinov en caso de que no estuvieras trolleando: la guía de Ruby Style no está escrita por los creadores de Ruby. Ruby fue creado por Yukihiro Matsumoto y otros, mientras que la Guía de Estilo Ruby fue principalmente por Bozhidar Batsov.
Andrew Grimm
2
@ AndrewGrimm, gracias, es bueno saberlo. Perdón por trollear, pero estoy sinceramente confundido con algunos aspectos de la realidad de rubí. Una cosa es segura: cada proyecto ruby ​​necesita políticas de estilo estrictas para mantener la base de código mantenible.
akostadinov
37

||y &&enlazar con la precedencia que espera de los operadores booleanos en lenguajes de programación ( &&es muy fuerte, ||es un poco menos fuerte).

andy ortienen menor prioridad.

Por ejemplo, a diferencia ||, ortiene menor prioridad que =:

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

Asimismo, a diferencia &&, andtambién tiene menor prioridad que =:

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

Además, a diferencia de &&y ||, andy se orunen con igual precedencia:

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

El enlace débil andy orpuede ser útil para fines de control de flujo: consulte http://devblog.avdi.org/2010/08/02/using-and-and-or-in-ruby/ .

Gabe Kopley
fuente
2
"a diferencia ||, ortiene menor prioridad que =" ... ahora tiene más sentido, ¡gracias!
Steph Sharp
18

andtiene menor prioridad que &&.

Pero para un usuario sin pretensiones, pueden surgir problemas si se usa junto con otros operadores cuya prioridad está en el medio, por ejemplo, el operador de asignación:

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
Santhosh
fuente
1
Gracias, pero ¿cómo es la precedencia de "y" diferente de "&&"?
BKSpurgeon
2
@BKSpurgeon Consulte aquí para obtener una lista ordenada de precedencia de operadores en Ruby.
thutt
5

andtiene menor precedencia, principalmente lo usamos como un modificador de flujo de control como if:

next if widget = widgets.pop

se convierte

widget = widgets.pop and next

Para or:

raise "Not ready!" unless ready_to_rock?

se convierte

ready_to_rock? or raise "Not ready!"

Prefiero usar ifpero no and, porque ifes más inteligible, así que simplemente ignoro andy or.

Consulte " Uso de" y "y" o "en Ruby " para obtener más información.

Feuda
fuente
0

No sé si esta es la intención de Ruby o si es un error, pero intente este código a continuación. Este código se ejecutó en Ruby versión 2.5.1 y estaba en un sistema Linux.

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

puts 1 > -1 && 257 < 256
# => true
Kevin Ng
fuente
1
@JakubArnold Sarcasm nunca es útil. Ejemplos a veces son.
BobRodes
@BobRodes No fue un sarcasmo. Hay 7 respuestas, 6 de las cuales ya tienen ejemplos.
Jakub Arnold
1
@JakubArnold Todavía encontré útil este ejemplo.
BobRodes
También estoy obteniendo resultados extraños. v1 = verdadero y falso p v1 # => app.rb: verdadero, IRB: falso v2 = verdadero && falso p v2 # => app.rb: falso, IRB: falso pone 1> -1 && 257 <256 # => app.rb: false, IRB: false
Rich_F