2010-02-01 10 views
9

Tengo dos versiones diferentes de un módulo Perl. Actualmente, la secuencia de comandos crucial utiliza la versión del módulo especificada por una variable de entorno y el sistema se basó en diferentes tareas ejecutadas por diferentes usuarios. El entorno del usuario determinará qué versión del módulo Perl se utilizó.¿Cómo cambio dinámicamente la ruta del módulo Perl?

Ahora me gustaría cambiar esto a la versión que se especifica dentro del script de Perl, es decir, según las opciones que se pasen. Lamentablemente, código como este:

if ($new){ use lib "newdir"; } 
else{ use lib "olddir"; } 
use module; 

no funciona. Perl simplemente agrega newdir y luego olddir a @INC y luego ejecuta el script.

¿Cómo especifico dinámicamente qué módulo usar?

Respuesta

15

Es necesario utilizar un bloque BEGIN{} por lo que su if - código else se llevará a cabo en tiempo de compilación:

BEGIN { 
    if ($new) { unshift @INC, "newdir"; } 
    else {  unshift @INC, "olddir"; } 
} 
use module; 

También puede establecer la variable de entorno PERL5LIB por lo que no tendría que hacer este tipo de configuración en el script.

+0

Su estilo de horquillado * extraño * le ha dejado un bloque no cerrado. (¡Ahora, para comenzar una guerra de horquillado!) – Axeman

+0

Eek. Gracias, Axeman. – mob

+1

También vale la pena mencionar que "use lib" y manipular @INC directamente no son siempre operaciones equivalentes. Ver los documentos para más detalles. – jrockway

12

Hay un pragma only en CPAN que facilita la instalación y el uso de múltiples versiones del mismo módulo.

3

Si prefiere que su lógica suceda en tiempo de ejecución (por ejemplo, si la variable $ new se produce de una forma más complicada que no desea ejecutar en un bloque BEGIN) puede usar require() cargar la módulo en tiempo de ejecución.

Lo importante a recordar es que

use Module; 
use ModuleWithExports qw(export1 export2); 

es la misma que

BEGIN { require Module; Module->import() } 
BEGIN { 
    require ModuleWithExports; 
    ModuleWithExports->import('export1', 'export2'); 
} 

Esto significa que para tener su código se ejecute en tiempo de ejecución se puede simplemente tener:

if ($new) { 
    unshift @INC, "newdir"; 
} 
else { 
    unshift @INC, "olddir"; 
} 
require module; 
module->import(); # if necessary 

Una alternativa al uso de require() es usar el módulo Module::Load de CPAN.

Cuestiones relacionadas