【问题标题】:How can I conditionally use a module in Perl?如何在 Perl 中有条件地使用模块?
【发布时间】:2011-04-26 03:01:21
【问题描述】:

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

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

if(Condition1)
{
  use $Module1;
}
elsif(Condition2)
{
  use $Module2;
}

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

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

@Array= @$Module1::Array_inside_module;

无论如何我可以做到这一点。某种编译器指令?

【问题讨论】:

    标签: perl module include conditional


    【解决方案1】:

    您可能会发现 if 模块对此很有用。

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

    BEGIN {
        my $module = $condition ? $Module1 : $Module2;
        my $file = $module;
        $file =~ s[::][/]g;
        $file .= '.pm';
        require $file;
        $module->import;
    }
    

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

    或者,您可以使用perlref 中记录的符号引用。但是,这通常是一种代码味道。

    my @array = do {
        no strict 'refs';
        @{ ${ "${Module}::Array_inside_module" } };
    };
    

    【讨论】:

    • +1 用于解决“我如何从我加载的任何模块调用具有相同名称的方法”:)
    • 我通常会在里面放一个 eval 以防你无法加载模块。我喜欢很好地关闭一切,而不是看到 perl 吐出的可怕的 @INC 转储。 :)
    【解决方案2】:

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

    如果您想访问同名的数组,无论您加载哪个模块,请考虑为此创建一个方法,这样您就可以跳过符号引用的内容。给每个模块一个同名的方法:

      package ReportHashFileFoo;
      our @some_package_variable;
      sub get_array { \@some_package_variable }
    

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

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

    我不知道你真正在做什么 (XY Problem),但可能有更好的设计。当事情看起来像这样棘手时,通常是因为您忽略了更好的解决方法。

    【讨论】:

      【解决方案3】:

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

      if (Condition1) {
          eval "use $Module1"; die $@ if $@;
      }
      elsif (Condition2) {
          eval "use $Module2"; die $@ if $@;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-07-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多