2010-10-15 48 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),但有可能是一個更好的設計。當事情看起來很棘手時,通常是因爲你忽視了更好的方法。

相關問題