代码之家  ›  专栏  ›  技术社区  ›  Mike

Perl,动态包含包

  •  6
  • Mike  · 技术社区  · 14 年前

    假设我有一个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 回复  |  直到 14 年前
        1
  •  9
  •   Eric Strom    14 年前

    这可以在不进行评估的情况下完成,如下所示:

    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
  •  5
  •   cjm    14 年前
    my $module_var = 'module';
    eval "use $module_var; 1" or die $@;
    my $module_instance = $module_var->new();
    

    请注意 eval 可能是个安全漏洞。如果 $module_var 包含代码,它将被执行。解决这个问题的方法之一是 Class::MOP . 替换 埃瓦 线与:

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

    如果不需要class::mop,可以复制 _is_valid_class_name 在代码中使用它,并确保 模值VAR 在您之前包含有效类 埃瓦 它。(请注意,如果您正在使用 Moose ,您已经在幕后使用了class::mop。)

        3
  •  0
  •   szbalint    14 年前

    你可以用 eval .

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