2012-06-13 10 views
13

¿Por qué este código no funciona?Ruby si frente al final de la línea si se comporta de manera diferente?

b if b = true 

error: undefined local variable or method `b'

Pero esto:

if b = true 
    b 
end 

¿No deberían ser los mismos?

+2

Se puede incluso simplificar: 'k si k = 1' y' si k = 1; k; end' – Flexoid

+0

Esto ha sido una pequeña molestia para mí; No creo que haya una razón profunda por la que su código no funcione, por lo que tal vez agreguen esta característica en la próxima versión de ruby. –

+0

Los condicionales son expresiones como cualquier otra cosa en Ruby, por lo que se espera que este comportamiento cuando el analizador está buscando asignar variables, y sería difícil de cambiar. Sin embargo, estoy de acuerdo en que es bastante intuitivo y no sigue el principio de la menor sorpresa. –

Respuesta

15

Esta es una muy buena pregunta. Tiene que ver con el alcance de las variables en Ruby.

Aquí es una post by Matz on the Ruby bug tracker en esto:

local variable scope determined up to down, left to right. So a local variable first assigned in the condition of if modifier is not effective in the left side if body. It's a spec.

+1

+1 para la referencia. –

+0

Gracias por la razón. –

+0

+1 gran referencia – KensoDev

2

En la primera versión tan pronto como se golpea k, el analizador vomita porque no se ha visto todavía.

En la segunda versión, k es parte de una expresión de asignación y se analiza de forma diferente.

2

No sé la razón, pero el problema es que el intérprete intenta buscar la variable k antes de evaluar la condición.

Si usted lo escribe así, no habrá ningún error y funciona como se esperaba:

k = nil 
h = {k: 1} 
v = k if k = h.delete(:k) 
0

Debido a que el intérprete de Ruby crea una variable local cuando ve una asignación

En el segundo caso, que aún no ha visto la asignación , por lo que la variable no existe cuando se analiza la expresión.

Para ser más precisos, un método primero se analiza en una representación interna, y luego, quizás, el código finalmente se llamará y se ejecutará realmente.

Las variables locales son creado en ese pase de análisis. Es una cuestión de declaración, solo significa que el intérprete se da cuenta de ellos. No se crearán en el sentido de que se les dé espacio o un valor hasta que alguien llame al método circundante.

Cuestiones relacionadas