2010-10-15 10 views
13

quiero hacer algo como esto en Perl:¿Cómo puedo usar condicionalmente un módulo en Perl?

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

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

ReportHashFile * .pm contiene un paquete de ReportHashFile *.

¿También cómo hacer referencia a una matriz dentro del módulo en función del nombre del módulo dinámico?

@Array= @$Module1::Array_inside_module; 

De todos modos, puedo lograrlo. ¿Algún tipo de directiva de compilación?

Respuesta

22

Puede encontrar el módulo if útil para esto.

De lo contrario, la idea básica es usar require, que ocurre en tiempo de ejecución, en lugar de use, que ocurre en tiempo de compilación. Tenga en cuenta que '

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

En cuanto a abordar globales, podría ser más fácil si usted acaba de exportar la variable o una función que devuelve a la persona que llama, que se puede utilizar por su nombre no calificado. De lo contrario, también existe la posibilidad de utilizar un método y llamarlo como $Module->method_name.

Alternativamente, podría utilizar referencias simbólicas documentadas en perlref. Sin embargo, eso es bastante olor a código.

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

+1 para el direccionamiento "¿Cómo puedo llamar a un método con el mismo nombre de cualquier módulo que cargué?" :) – DVK

+0

Normalmente lanzo una evaluación allí en caso de que no pueda cargar el módulo. Me gusta cerrar las cosas muy bien en lugar de ver ese horrible vertedero de @INC que perl escupe. :) –

5

La gente ya le han dicho cómo se puede cargar el módulo con las primitivas de Perl. También hay Module::Load::Conditional.

Si está buscando acceder a una matriz con el mismo nombre, sin importar qué módulo cargó, considere crear un método para que pueda omitir las referencias simbólicas. Dar a cada módulo de un método del mismo nombre:

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

Entonces, cuando se carga ese módulo:

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

No sé lo que estás haciendo en realidad (XY Problem), pero es probable que haya un mejor diseño. Cuando las cosas parecen complicadas como esta, por lo general es porque estás pasando por alto una mejor manera de hacerlo.

Cuestiones relacionadas