2010-10-15 19 views
13

Voglio fare qualcosa di simile in Perl:Come posso usare condizionatamente un modulo in Perl?

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

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

ReportHashFile * .pm contiene un pacchetto di ReportHashFile *.

Inoltre, come fare riferimento a un array all'interno del modulo in base al nome del modulo dinamico?

@Array= @$Module1::Array_inside_module; 

È comunque possibile ottenere ciò. Una sorta di direttiva del compilatore?

risposta

22

È possibile che il modulo if sia utile per questo.

In caso contrario, l'idea di base è utilizzare require, che avviene in fase di esecuzione anziché in use, che avviene in fase di compilazione. Si noti che '

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

Per quanto riguarda l'indirizzamento globali, potrebbe essere più facile se appena esportato la variabile o una funzione che restituisce al chiamante, che è possibile utilizzare con il suo nome non qualificato. Altrimenti c'è anche la possibilità di usare un metodo e chiamarlo come $Module->method_name.

In alternativa, è possibile utilizzare riferimenti simbolici come documentato in perlref. Tuttavia, questo è solitamente un odore di codice.

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

+1 per l'indirizzamento "Come si chiama un metodo con lo stesso nome dal modulo che ho caricato" :) – DVK

+0

Di solito lancio una valutazione in quel caso nel caso in cui non si riesca a caricare il modulo. Mi piace chiudere le cose molto bene invece di vedere quella terribile discarica di @INC che perl sputa fuori. :) –

5

La gente ha già detto come si può caricare il modulo con primitive Perl. C'è anche Module::Load::Conditional.

Se stai cercando di accedere a un array con lo stesso nome, indipendentemente dal modulo che hai caricato, prendi in considerazione la possibilità di creare un metodo in modo da poter saltare il riferimento simbolico. Dare ad ogni modulo di un metodo con lo stesso nome:

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

Poi, quando si carica quel modulo:

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

Non so quello che stai facendo veramente (XY Problem), ma probabilmente c'è un design migliore. Quando le cose sembrano complicate, di solito è perché stai trascurando un modo migliore per farlo.

Problemi correlati