Perl, dynamically include package
Let's say I have a perl module file and开发者_JS百科 I want to include and use it dynamically at runtime. Said module includes a class that I need to instantiate without knowing its name until runtime.
For example,
#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();
This can be done without eval as follows:
my $module_name = 'Some::Module';
(my $require_name = $module_name . ".pm") =~ s{::}{/}g;
require $require_name;
my $obj = $module_name->new();
If you need to do this many times, just wrap up that code in a subroutine:
sub load_module {
for (@_) {
(my $file = "$_.pm") =~ s{::}{/}g;
require $file;
}
}
load_module 'Some::Module', 'Another::Module';
my $module_var = 'module';
eval "use $module_var; 1" or die $@;
my $module_instance = $module_var->new();
Note that the eval
is a possible security hole. If $module_var
contains code, it will get executed. One way around this is to use Class::MOP. Replace the eval
line with:
use Class::MOP;
Class::MOP::load_class($module_var);
If you don't want to require Class::MOP, you could copy the _is_valid_class_name
function from it into your code, and just make sure that $module_var
contains a valid class before you eval
it. (Note that if you're using Moose, you're already using Class::MOP behind-the-scenes.)
You can do this with eval
.
my $module = "Foo";
eval "use $module;1" or die($@); # Couldn't load module
精彩评论