2010-10-15 11 views
13

Ich möchte in Perl, so etwas tun:Wie kann ich ein Modul in Perl bedingt verwenden?

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

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

ReportHashFile * .pm enthält ein Paket ReportHashFile *.

Auch, wie man ein Array innerhalb des Moduls referenziert, das auf dynamischem Modulnamen basiert?

@Array= @$Module1::Array_inside_module; 

Gibt es trotzdem kann ich das erreichen. Eine Art Compiler-Direktive?

Antwort

22

Sie könnten das if Modul dafür nützlich finden.

Ansonsten ist die Grundidee, require zu verwenden, was zur Laufzeit statt use geschieht, was zur Kompilierzeit geschieht. Beachten Sie, dass '

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

Was Globals Adressierung, könnte es einfacher sein, wenn Sie nur die Variable oder eine Funktion exportiert sie an den Aufrufer zurückkehrt, die Sie durch seine unqualifizierten Namen benutzen konnten. Ansonsten besteht auch die Möglichkeit, eine Methode zu verwenden und sie als $Module->method_name zu benennen.

Alternativ können Sie symbolische Referenzen verwenden, wie in perlref dokumentiert. Das ist normalerweise ein ziemlich übler Geruch.

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

+1 für die Adressierung "Wie rufe ich eine Methode mit dem gleichen Namen von dem Modul auf, das ich geladen habe" :) – DVK

+0

Ich werfe normalerweise ein Eval ein, falls Sie das Modul nicht laden können. Ich mag es, die Dinge gut zu machen, anstatt diesen schrecklichen Müll von @INC zu sehen, den Perl ausspuckt. :) –

5

Menschen haben bereits ihr gesagt, wie Sie das Modul mit Perl Primitiven laden kann. Es gibt auch Module::Load::Conditional.

Wenn Sie auf ein Array mit dem gleichen Namen zugreifen möchten, egal welches Modul Sie geladen haben, sollten Sie eine Methode dafür in Betracht ziehen, damit Sie das symbolische Referenzmaterial überspringen können. Geben Sie jeden Modul ein Verfahren mit dem gleichen Namen:

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

Dann, wenn Sie das Modul laden:

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

Ich weiß nicht, was Sie wirklich (XY Problem) zu tun, aber es ist wahrscheinlich ein besseres Design. Wenn die Dinge so schwierig scheinen, liegt es meist daran, dass Sie einen besseren Weg dorthin übersehen.

Verwandte Themen