【问题标题】:Perl, dynamically include packagePerl,动态包含包
【发布时间】:2011-03-29 02:16:48
【问题描述】:

假设我有一个 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();

【问题讨论】:

  • 一个更好更现代的想法是创建一个基类,并将这些动态加载的实体分解为MooseX::Traits,然后您只需使用上述特征实例化基类BaseClass->with_traits('Foobar::Baz')->new;

标签: perl dynamic module


【解决方案1】:

这可以在没有 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';

【讨论】:

    【解决方案2】:
    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。)

    【讨论】:

    • 有没有比 eval 更安全的方法?安全是我关心的问题
    【解决方案3】:

    您可以使用eval 来做到这一点。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-10-05
      • 2015-11-04
      • 1970-01-01
      • 2012-05-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-04
      相关资源
      最近更新 更多