2010-08-12 12 views
6

Digamos que tengo un archivo de módulo perl y quiero incluirlo y usarlo dinámicamente en el tiempo de ejecución. Dicho módulo incluye una clase que necesito crear una instancia sin conocer su nombre hasta el tiempo de ejecución.Perl, incluir dinámicamente el paquete

Por ejemplo,

#inside module.pm 

package module; 

sub new { 
#setup object 
} 

#inside main.pl 

#get module.pm as argument 
my $module_var = #load reference to module using text argument? 
my $module_instance = $module_var->new(); 
+4

Un mejor más la idea moderna crearía una clase base, y factorizaría estas entidades cargadas dinámicamente como 'MooseX :: Traits', luego solo crearas una instancia de la clase base con dichos rasgos' BaseClass-> with_traits ('Foobar :: Baz') -> new; ' –

Respuesta

9

Esto puede hacerse sin eval de la siguiente manera:

my $module_name = 'Some::Module'; 

(my $require_name = $module_name . ".pm") =~ s{::}{/}g; 

require $require_name; 

my $obj = $module_name->new(); 

Si necesita hacer esto muchas veces, simplemente concluir que el código en una subrutina:

sub load_module { 
    for (@_) { 
     (my $file = "$_.pm") =~ s{::}{/}g; 
     require $file; 
    } 
} 

load_module 'Some::Module', 'Another::Module'; 
+2

['Module :: Load'] (http://p3rl.org/Module::Load) existe por esta razón. – daxim

5
my $module_var = 'module'; 
eval "use $module_var; 1" or die [email protected]; 
my $module_instance = $module_var->new(); 

Tenga en cuenta que la eval es un posible agujero de seguridad. Si $module_var contiene código, se ejecutará. Una forma de evitar esto es usar Class::MOP. Vuelva a colocar la línea eval con:

use Class::MOP; 
Class::MOP::load_class($module_var); 

Si no desea que se requiera Clase :: MOP, se puede copiar la función _is_valid_class_name de ella en su código, y sólo asegúrese de que $module_var contiene una clase válida antes eval it. (Tenga en cuenta que si usted está utilizando Moose, ya está usando RP Clase :: detrás de las escenas.)

+0

hay una manera más segura t han eval? la seguridad es una preocupación para mí – Mike

0

Usted puede hacer esto con eval.

my $module = "Foo"; 
eval "use $module;1" or die([email protected]); # Couldn't load module 
Cuestiones relacionadas