Perl, динамически включать пакет - PullRequest
6 голосов
/ 12 августа 2010

Допустим, у меня есть файл модуля perl, и я хочу включить и использовать его динамически во время выполнения. Упомянутый модуль включает в себя класс, который мне нужно создать, не зная его имени до времени выполнения.

Например,

#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();

Ответы [ 3 ]

9 голосов
/ 12 августа 2010

Это можно сделать без eval следующим образом:

my $module_name = 'Some::Module';

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

require $require_name;

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

Если вам нужно делать это много раз, просто закройте этот код в подпрограмме:

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

load_module 'Some::Module', 'Another::Module';
5 голосов
/ 12 августа 2010
my $module_var = 'module';
eval "use $module_var; 1" or die $@;
my $module_instance = $module_var->new();

Обратите внимание, что eval - это возможная дыра в безопасности. Если $module_var содержит код, он будет выполнен. Одним из способов решения этой проблемы является использование Class :: MOP . Заменить строку eval на:

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

Если вы не хотите требовать Class :: MOP, вы можете скопировать из него функцию _is_valid_class_name в свой код и просто убедиться, что $module_var содержит допустимый класс перед вами eval. (Обратите внимание, что если вы используете Moose , вы уже используете Class :: MOP за кулисами.)

0 голосов
/ 12 августа 2010

Вы можете сделать это с помощью eval.

my $module = "Foo";
eval "use $module;1" or die($@); # Couldn't load module
...