2010-04-15 19 views
15

Sé que es posible usar una variable como nombre de variable para variables de paquete en Perl. Me gustaría usar los contenidos de una variable como un nombre de módulo. Por ejemplo:¿Cómo puedo usar una variable como nombre de módulo en Perl?

package Foo; 
our @names =("blah1", "blah2"); 
1; 

Y en otro archivo que desea ser capaz de ser capaz de establecer el contenido de un escalar a "foo" y luego acceder a la matriz a través nombres en Foo que escalar.

my $packageName = "Foo"; 

Básicamente quiero hacer algo en la línea de:

@{$packageName}::names; #This obviously doesn't work. 

Sé que puedo usar

my $names = eval '$'. $packageName . "::names" 

Pero sólo si Foo::names es un escalar. ¿Hay otra forma de hacerlo sin la declaración eval?

+0

¿Qué quiere decir con "access Foo"? – Ether

+0

Editado la pregunta. Quiero poder acceder a la variable del paquete "@names" dentro de foo – mjn12

Respuesta

14

para llegar a variables de paquete en paquete $package, puede utilizar simbólica referencias:

no strict 'refs'; 
my $package = 'Foo'; 

# grab @Foo::names 
my @names = @{ $package . '::names' } 

una mejor manera, lo que evita referencias simbólicas, es exponer un método dentro Foo que devolverá la matriz. Esto funciona porque el operador de invocación de método (->) puede tomar una cadena como invocant.

package Foo; 

our @names = (...); 
sub get_names { 
    return @names; 
} 

package main; 
use strict; 

my $package = 'Foo'; 
my @names = $package->get_names; 
+0

¿No hay parientes en get_names? –

+0

Creo que me gusta el método alternativo que describiste, siempre que pueda definir get_names en la clase base de Foo (lo llamaremos Bar para ser original) de esa forma puedo definir @names en cada clase que herede de Bar. Estoy usando objetos Moose si eso hace alguna diferencia. – mjn12

+1

@Paul, no se requieren paréntesis en las llamadas a métodos si no hay argumentos. Algunas personas prefieren incluir siempre un '()' vacío para la coherencia, pero generalmente las omito si puedo. – friedo

4

Strict checking le impide el uso de una variable (o cadena literal) como parte de un nombre, pero esto se puede desactivar de forma local:

my @values; 
{ 
    no strict 'refs'; 
    @values = @{"Mypackage"}::var; 
} 
+0

. Esencialmente, lo que estoy haciendo es englobar un directorio para * .pm y luego, para cada archivo, encuentro que necesito $ nombre de archivo. Una vez cargados esos módulos, necesito acceder a la variable @names definida dentro de cada paquete. No sé el nombre del paquete hasta el tiempo de ejecución, todo lo que tengo es una variable que contendrá el nombre del paquete. – mjn12

+0

No tengo problemas para cargar paquetes de un nombre de variable. Tengo esa parte desactivada. Está accediendo a las variables dentro de esos paquetes. Sin embargo, esta respuesta definitivamente me hubiera ahorrado mucho google hace una hora :) – mjn12

+0

@mjn: perdón, estoy editando mi respuesta ahora para resaltar el problema real :) – Ether

Cuestiones relacionadas