2010-02-25 15 views
6

¿Por qué esta impresión 42:¿Por qué no puedo usar el valor de una variable de Perl para acceder a un nombre de variable léxica?

$answer = 42; 
$variable = "answer"; 

print ${$variable} . "\n"; 

pero esto no lo hace:

my $answer = 42; 
my $variable = "answer"; 

print ${$variable} . "\n"; 
+0

Supongo que $ answer define un alcance global, y mi $ answer define un ámbito local. –

+0

@Paul, pero print $ answer funcionaría bien .... ¿cómo $ {$ variable} crea un ámbito global? – ennuikiller

+2

Siempre use 'use strict; usa advertencias; 'y nunca verás este problema. Aún mejor, nunca use el valor de una variable para obtener otra variable. Hashes es mucho mejor. – Ether

Respuesta

15

Solo las variables del paquete (el tipo declarado en su primer ejemplo) se pueden segmentar a través de referencias simbólicas. Las variables léxicas (my) no pueden ser, por lo que su segundo ejemplo falla.

Consulte el excelente artículo Coping with Scoping sobre cómo funcionan los dos sistemas variables por separado en Perl. Y vea también el excelente Why it's stupid to use a variable variable name para saber por qué es estúpido. :)

6

Perl tiene dos sistemas de variables totalmente independientes pero en gran medida compatibles, variables de paquete, como en el primer ejemplo, y léxica variables, como en el segundo. Hay algunas cosas que cada uno puede hacer, pero la otra no puede:

variables de paquete son los únicos que pueden ser:

  1. localizada (con local)
  2. utilizar como destino para una referencia simbólica (la razón por la segunda obra duerma ejemplo de la OP)
  3. utilizado como barewords (definiciones sub, manejadores de archivo)
  4. utilizarse con typeglobs (porque eso es lo que realmente es el símbolo debajo del capó)

Las variables léxicas son las únicas que se pueden cerrar (se utilizan en un cierre léxico).

El uso estricto ayudaría forzándolo a declarar las variables del paquete con our, haciendo la diferencia más clara.

Hay varios momentos en los que las referencias simbólicas son útiles en Perl, la mayoría se centran en la manipulación de la tabla de símbolos (como escribir su propio import en un módulo en lugar de utilizar Exporter,, varias otras tareas de programación meta mono-parches módulos en tiempo de ejecución) Todos estos son temas avanzados.

Para otras tareas, generalmente hay una mejor manera de hacerlo, como con un hash. La regla general es ejecutar siempre bajo use warnings; use strict; a menos que sepa que no hay otra forma más que deshabilitar una parte del pragma (como usar no strict 'refs'; en un alcance tan pequeño como sea posible).

4

El problema es que no puede usar una referencia simbólica para referirse a una variable léxica. En ambos ejemplos, ${$variable} está buscando $main::answer. En el primero, $answer es un paquete global y abreviado para $main::answer, por lo que la referencia lo encuentra. En el segundo, $answer es una variable léxica y no vive en ningún paquete, por lo que la referencia no puede encontrarlo.

Más detalles en perlref bajo el encabezado Symbolic references.

5

Las referencias simbólicas solo funcionan con las variables del paquete. La tabla de símbolos no rastrea las variables léxicas (que es el punto entero de que sean léxicas :).

Cuestiones relacionadas