2009-12-03 9 views
14

Tengo una pregunta sobre las palabras clave/& &/= en Ruby.Prioridad del operador para And/&& en Ruby

Los ruby ​​dicen que la precedencia para las palabras clave mencionadas es: (1) & &, (2) =, (3) y.

que tienen este fragmento de código que he escrito:

def f(n) 
n 
end 

if a = f(2) and b = f(4) then 
    puts "1) #{a} #{b}" 
end 

if a = f(2) && b = f(4) then 
    puts "2) #{a} #{b}"  
end 

la salida es:

1) 2 4 [esperado]

2) 4 4 [? Por qué]

Por algún motivo, al usar & &, ¿se pueden evaluar tanto a como b para 4?

Respuesta

23

yo no entiendo muy bien la pregunta que usted está pidiendo. Es decir, usted tiene ya dado la respuesta usted mismo, antes incluso de hacer la pregunta: && une más apretado que = mientras and se une menos fuertemente que =.

Así, en el primer caso, la expresión se evalúa de la siguiente manera:

(a=f(2)) and (b=f(4)) 
(a= 2 ) and (b=f(4)) 
     2  and (b=f(4)) # a=2 
     2  and (b= 4 ) # a=2 
     2  and  4 # a=2; b=4 
         4 # a=2; b=4 

En el segundo caso, la evaluación es el siguiente:

a = ( f(2) && (b=f(4)) ) 
a = ( 2 && (b=f(4)) ) 
a = ( 2 && (b= 4 ) ) 
a = ( 2 &&  4 ) # b=4 
a =     4  # b=4 
         4  # b=4; a=4 
2

De Programming Ruby 1.9:

La única diferencia en las dos formas es precedencia (and se une más baja que &&).

-6

si modifica su código como esto va a obtener lo que espera

def f(n) 
    n 
end 

if (a = f(2) and b = f(4)) then 
    puts "1) #{a} #{b}" 
end 

if (a = f(2) and b = f(4)) then 
    puts "2) #{a} #{b}"   
end 

1) 2 4

2) 2 4

21

La razón es simple: la precedencia. Como usted dice, el orden es:

  1. & &
  2. =
  3. y

Desde && ha precedencia sobre =, se evaluó la sentencia como esta:

if a = (f(2) && (b = f(4))) then 

Que resultados:

if a = (2 && 4) then 

Cuando x y y son enteros, x && y devuelve y. Por lo tanto, 2 && 4 resulta en a = 4.

Para efectos de comparación, el primero se evalúa así:

if (a = f(2)) and (b = f(4)) then 
+0

Lo que no entiendo en su ejemplo es por qué no sería evaluado como: 'if a = (f (2) && b) = f (4) entonces' – nus

0

No sé las reglas específicas eso puede ayudar en esta situación, pero usemos las prioridades de las operaciones. Utilizando las reglas de prioridades, podemos dividir el cálculo de la segunda expresión en varios pasos

1 f(2) && b => expr1 
2 expr1 = f(4) => expr2 
3 a = expr2 

obvio que en el paso 2 que conseguimos una situación incorrecta - en el lado izquierdo de la = es rvalue - objeto temporal, el cual no se puede asignar por ningún valor. Supongo que el analizador sintáctico rompe las reglas de la evaluación prioritaria de las expresiones cuando se encuentran con tales situaciones. Más detalles sobre los cálculos de expresiones se pueden encontrar here

Cuestiones relacionadas