2009-08-03 21 views
9

Hola estoy usando un script Perl escrito por otra persona que ya no está en la empresa. Si ejecuto el script como independiente, entonces el resultado es el esperado. Pero cuando llamo repetidamente al script desde otro código, el resultado es incorrecto excepto por primera vez.¿Cómo puedo forzar la descarga de un módulo Perl?

sospecho que algunas variables no se inicializan correctamente. Cuando se llama independiente, cada vez que sale y todos los valores de las variables se inicializan a los valores predeterminados. Pero cuando se llama desde otro script de Perl, los módulos y los valores de las variables probablemente se transfieren a la siguiente llamada del script.
¿Hay alguna manera de eliminar el script llamado desde la memoria antes de que llame la próxima vez?

He intentado que permite la advertencia y estaba vomitando 1000 de líneas de advertencia ...!

EDIT: ¿Cómo estoy llamando la otra secuencia de comandos:

El código es el siguiente:

do "processing.pl"; 
... 
... 
... 

process(params); #A function in processing.pl 
... 
... 
... 
+1

¿Cómo llamas a ese otro script? – innaM

+0

Por favor, mira la edición. Avísame si no está claro. – Manoj

Respuesta

4

Si no desea reescribir/corregir el script, le sugiero que llame al script a través del exec() o una de sus variedades. Si bien no es muy elegante, definitivamente solucionará tu problema.

+1

¿Cómo soluciona esto el problema? ¿Estás pensando en bifurcar el procesamiento y luego en ejecutar? –

+2

El problema con el uso de 'exec' es que no se puede llamar a la función 'proceso' porque no se ha cargado en el programa. Por lo tanto, debería preocuparse por cómo recuperar la información del programa ejecutado en un formato que Perl pueda administrar. Supongo que algún tipo de salida formateada que generó una cadena que, cuando se evalúa, inicializó una variable, podría funcionar, pero podría ser más simple simplemente continuar limpiando o reescribiendo el código. –

11

Si desea forzar el módulo que se va a cargar, borrar su entrada de %INC y vuelva a cargar eso.

Por ejemplo:

sub reload_module { 
    delete $INC{'Your/Silly/Module.pm'}; 
    require Your::Silly::Module; 
    Your::Silly::Module->import; 
} 

Tenga en cuenta que si este módulo se basa en variables globales en otros módulos que se establecen, los pueden necesitar ser recargado también. No hay una manera fácil de saber sin tener un pico en el código.

+2

Module :: Reload se encargará de esos detalles, pero también tenga en cuenta mi comentario para ver la respuesta. –

+0

@Brian: does Module :: Reload se ocupa de los problemas que Module :: Unload no tiene? ¿Puede, de hecho? –

0

¿Otra posibilidad (solo pensar en voz alta aquí) podría tener que ver con el directorio local? Están corriendo desde el mismo lugar. Sin embargo, probablemente no funcionaría la primera vez.

Otra opción es usar system ('doprocessing.pl');. Perezosamente, lo hacemos con un par de secuencias de comandos para forzar la re-inicialización de un número de clases/variables etc. Y para obligar a los archivos de registro para girar correctamente.

editar: Acabo de volver a leer su pregunta, y parece que no la está llamando así.

5

La descarga de un módulo es una tarea más difícil que simplemente eliminar la entrada% INC del módulo. Eche un vistazo al Class::Unload de CPAN.

+7

Tenga en cuenta que Class :: Unload no es una solución directa a este problema. Su objetivo es limpiar cualquier cosa dentro de un paquete en particular. No deshace todo lo demás que un módulo podría haber hecho, como jugar con variables especiales de Perl, definir cualquier cosa en otras clases (algo que hago con frecuencia), o cualquier otra cosa que un módulo pueda hacer que no involucre el símbolo mesa. –

+0

Tienes razón, por supuesto. Pensé que recordaba que los documentos Class :: Unload tenían una sección CAVEAT, pero estaba equivocado. – tsee

8

Hola Estoy usando un script de perl escrito por otra persona que ya no está en la empresa. He intentado que permite la advertencia y estaba vomitando 1000 de líneas de advertencia ...!

Allí está su problema. La secuencia de comandos no se escribió correctamente y se debe volver a escribir.

Hazte esta pregunta: si tiene 1000s de advertencias cuando habilitas la comprobación estricta, ¿cómo puedes estar seguro de que está haciendo lo correcto? ¿Cómo puede estar seguro de que no está arruinando archivos, destruyendo conjuntos de datos, arruinando su sistema de archivos? Lo más probable es que esté haciendo todas estas cosas, ya sea de forma deliberada o accidental.

No me gustaría confiar en ejecutar un script lleno de errores escrito por alguien que ya no está en la empresa. Lo volvería a escribir y estar seguro de que estaba haciendo lo que necesitaba.

+1

Incluso si no hay advertencias, aún no sabe si está haciendo lo correcto. Las advertencias cambian con las versiones de Perl, por lo que no hay mucho que pueda inferir simplemente por recibir muchas advertencias. –

+2

Podría inferir una base de código descuidada que debería ser priorizada para la reescritura :) Pero de acuerdo, la ausencia de advertencias no es indicativa de la ausencia de errores. – Ether

3

¿Está seguro de que necesita volver a cargar el módulo? Al usar do, está leyendo la fuente cada vez y ejecutándola. ¿Qué sucede si cambia eso a require, que solo leerá y evaluará la fuente una vez?

Cuestiones relacionadas