如何在Perl中有条件地使用模块?

Jea*_*ean 16 perl conditional module include

我想在Perl中做这样的事情:

$Module1="ReportHashFile1"; # ReportHashFile1.pm
$Module2="ReportHashFile2"; # ReportHashFile2.pm

if(Condition1)
{
  use $Module1;
}
elsif(Condition2)
{
  use $Module2;
}
Run Code Online (Sandbox Code Playgroud)

ReportHashFile*.pm包含一个包ReportHashFile*.

另外如何根据动态模块名称引用模块内部的数组?

@Array= @$Module1::Array_inside_module;
Run Code Online (Sandbox Code Playgroud)

无论如何我能做到这一点.某种编译器指令?

raf*_*afl 23

您可能会发现该if模块对此非常有用.

否则,基本思想是使用require,它在运行时发生,而不是use在编译时发生.注意 '

BEGIN {
    my $module = $condition ? $Module1 : $Module2;
    my $file = $module;
    $file =~ s[::][/]g;
    $file .= '.pm';
    require $file;
    $module->import;
}
Run Code Online (Sandbox Code Playgroud)

至于寻址全局变量,如果你只是导出变量或将函数返回给调用者,可能会更容易,你可以使用它的非限定名称.否则,也可以使用方法并将其称为$Module->method_name.

或者,您可以使用符号引用,如中所述perlref.然而,这通常是代码味道.

my @array = do {
    no strict 'refs';
    @{ ${ "${Module}::Array_inside_module" } };
};
Run Code Online (Sandbox Code Playgroud)


Eug*_*ash 9

除非执行速度很重要,否则可以使用字符串eval:

if (Condition1) {
    eval "use $Module1"; die $@ if $@;
}
elsif (Condition2) {
    eval "use $Module2"; die $@ if $@;
}
Run Code Online (Sandbox Code Playgroud)


bri*_*foy 5

人们已经告诉过你如何使用Perl原语加载模块.还有Module :: Load :: Conditional.

如果你想要访问一个同名的数组,无论你加载哪个模块,考虑为它制作一个方法,这样你就可以跳过符号引用的东西.为每个模块提供一个相同名称的方法:

  package ReportHashFileFoo;
  our @some_package_variable;
  sub get_array { \@some_package_variable }
Run Code Online (Sandbox Code Playgroud)

然后,当您加载该模块时:

  if( ... some condition ... ) {
       eval "use $module" or croak ...;
       my $array_ref = $module->get_array;
       }
Run Code Online (Sandbox Code Playgroud)

我不知道你在做什么(XY问题),但可能有更好的设计.当事情看起来像这样棘手时,通常是因为你忽视了一种更好的方式.


And*_* A. 5

也许有帮助...

一个调试的小例子。

sub DEBUG () {1};               # It's the condition (may be a debuglevel...)

use if DEBUG, Data::Dumper;     # Conditionally load

my $testvar = "foo";
print "Testing: $testvar\n" if     DEBUG;
print "No testing\n"        unless DEBUG;

print Dumper \$testvar if DEBUG;  # "Dumper" only available if "DEBUG" returns "true".

Run Code Online (Sandbox Code Playgroud)

输出与sub DEBUG () {1};

Testing: foo
$VAR1 = \'foo';
Run Code Online (Sandbox Code Playgroud)

输出与sub DEBUG () {0};

No testing
Run Code Online (Sandbox Code Playgroud)

qv perldoc.perl.org/if