2010-10-15 69 views
13

我想要做这样的事情在Perl:如何在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; 

有没有反正我可以做到这一点。某种编译器指令?

回答

22

您可能会发现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" } }; 
}; 
+0

+1用于解决“我如何调用与我加载的任何模块具有相同名称的方法”:) – DVK 2010-10-16 03:25:52

+0

我通常会在其中添加一个eval以防万一您无法加载模块。我喜欢关闭很好的东西,而不是看到perl吐出的@INC的可怕转储。 :) – 2010-10-16 18:53:44

5

人们已经告诉过你,你如何加载使用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),但有可能是一个更好的设计。当事情看起来很棘手时,通常是因为你忽视了更好的方法。

相关问题