2012-09-27 25 views

Respuesta

13

Es por la forma en que funciona el analizador de Ruby. Las variables son definidas por el analizador sintáctico, que recorre el código línea por línea, independientemente de si realmente se ejecutará.

Una vez que el analizador ve x =, define la variable local x (con valor nil) de ahora en adelante en el ámbito actual. Desde if/unless/case/for/while no cree un nuevo ámbito, x se define y está disponible fuera del bloque de código. Y dado que el bloque interno nunca se evalúa porque el condicional es falso, x no está asignado (y por lo tanto es nil).

Aquí hay un ejemplo similar:

defined?(x) and x = 0 
x #=> nil 

Tenga en cuenta que esta es una visión general más bien alto nivel de lo que sucede, y no es necesariamente exactamente cómo funciona el programa de análisis.

+0

Ah, sígueme. Buena explicación. – nneonneo

2

Esto tiene que ver con un capricho de las reglas de alcance de Ruby.

En ruby, una variable sin decorar x que aparece por sí sola podría ser una variable local o una llamada a un método: la gramática no puede decir cuál. Depende del analizador el descifrarlo ya que resuelve las referencias de variables locales. La regla es simple: si ya se ha visto una asignación a una variable del mismo nombre en el ámbito local, entonces la referencia es una variable local y la referencia está vinculada a esa variable local. De lo contrario, es una llamada a método, y se buscará como tal en tiempo de ejecución.

Las referencias de variables locales en Ruby se optimizan en búsquedas de arreglos (a cada variable local se le asigna un 'intervalo', y las referencias de variables locales encuadernadas generadas por el analizador se convierten en referencias de intervalos). La matriz se inicializa con toda nil:

/* initialize local variables */ 
for (i=0; i < local_size; i++) { 
    *sp++ = Qnil; 
} 

Por lo tanto, si se hace referencia a una variable local que no ha sido asignado, a través de una cota de referencia local (que sólo puede suceder si había una asignación saltado por encima de la referencia en el mismo alcance local), obtiene nil.

1

pensé que su pregunta era interesante así que traté de mirar hacia arriba y encontramos este: I don't understand ruby local scope

La respuesta correcta parece ser puesto Jorg.

veamos lo que sucede cuando se intenta acceder a una variable que no se ha inicializado:

NameError: undefined local variable or method `UNDECLAREDVAR' for main:Object 

La excepción indica que no está disponible para evaluar si una variable o método. La razón por la que no arroja la misma excepción es porque las variables locales no inicializadas se establecen en nil. Entonces puts x está bien porque el intérprete sabe que x es variable pero no inicializada y no es un método.

Cuestiones relacionadas