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();
6
задан Mike 12 August 2010 в 18:15
поделиться

3 ответа

Это можно сделать без 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';
9
ответ дан 8 December 2019 в 17:17
поделиться
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 за кадром.)

5
ответ дан 8 December 2019 в 17:17
поделиться

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

my $module = "Foo";
eval "use $module;1" or die($@); # Couldn't load module
0
ответ дан 8 December 2019 в 17:17
поделиться
Другие вопросы по тегам:

Похожие вопросы: