Aquí hay un escenario. Tiene una gran cantidad de scripts heredados, todos usan una biblioteca común. Dichos scripts usan la instrucción 'print' para salida de diagnóstico. No se permiten cambios a los guiones: tienen un amplio alcance, tienen sus aprobaciones y hace tiempo que dejaron los fructíferos valles de la supervisión y el control.¿Cómo puedo conectarme a la impresión de Perl?
Ahora ha llegado una nueva necesidad: el registro ahora debe agregarse a la biblioteca. Esto debe hacerse de forma automática y transparente, sin que los usuarios de la biblioteca estándar tengan que cambiar sus scripts. Los métodos de biblioteca comunes simplemente pueden tener llamadas de registro agregadas a ellos; esa es la parte fácil. La parte difícil radica en el hecho de que la salida de diagnóstico de estos scripts siempre se muestra con la instrucción 'print'. Esta salida de diagnóstico debe ser almacenada, pero igual de importante, procesada.
Como ejemplo de este procesamiento, la biblioteca solo debe registrar las líneas impresas que contienen las palabras 'advertencia', 'error', 'aviso' o 'atención'. El código de ejemplo a continuación extremadamente trivial y artificial (tm) grabaría algunos de dicha salida:
sub CheckPrintOutput
{
my @output = @_; # args passed to print eventually find their way here.
foreach my $value (@output) {
Log->log($value) if $value =~ /warning|error|notice|attention/i;
}
}
(me gustaría evitar cuestiones tales como 'lo que en realidad se debería registrar', 'impresión no debe utilizarse para diagnósticos ',' perl sucks ', o' este ejemplo tiene los defectos xy y z '... esto se simplifica enormemente por brevedad y claridad.)
El problema básico se reduce a la captura y procesamiento de datos pasados para imprimir (o cualquier perl incorporado, a lo largo de esas líneas de razonamiento). ¿Es posible? ¿Hay alguna forma de hacerlo limpiamente? ¿Hay algún módulo de registro que tenga ganchos para poder hacerlo? ¿O es algo que debería evitarse como la peste, y debería dejar de capturar y procesar la salida impresa?
Adicional: Debe ejecutarse multiplataforma: Windows y * nix por igual. El proceso de ejecución de los scripts debe ser el mismo, al igual que el resultado del script.
adicional adicional: Una sugerencia interesante hecho en los comentarios de la respuesta de codelogic:
Usted puede subclase http://perldoc.perl.org/IO/Handle.html y crear su propia identificador de archivo, que va a hacer el trabajo de registro. - Kamil Kisiel
Esto podría hacerlo, con dos salvedades:
1) que iba a necesitar una manera de exportar esta funcionalidad para cualquier persona que utiliza la biblioteca común. Tendría que aplicarse automáticamente a STDOUT y probablemente a STDERR también.
2) La documentación de the IO::Handle dice que no se puede crear una subclase, y mis intentos hasta ahora han sido infructuosos. ¿Se necesita algo especial para hacer que sublclassing IO :: Handle funcione? El estándar 'base de uso' IO :: Handle 'y luego anula los métodos nuevos/de impresión parecen no hacer nada.
Edición final: parece que IO :: Handle es un callejón sin salida, pero Tie :: Handle puede hacerlo. Gracias por todas las sugerencias; todos son realmente buenos Voy a probar la ruta Tie :: Handle. Si causa problemas, ¡volveré!
Adición: Tenga en cuenta que después de trabajar con esto un poco, encontré que Tie :: Handle funcionará, si no hace nada complicado. Si utiliza alguna de las características de IO :: Handle con su STDOUT o STDERR vinculado, es básicamente un crapshoot para que funcionen de manera confiable. No pude encontrar la manera de hacer que el método de autoenjuague de IO :: Handle funcione en mi atadura. encargarse de. Si habilitaba autoflush antes de atar el mango, funcionaría.Si eso funciona para usted, la ruta de Tie :: Handle puede ser aceptable.
Entonces, ¿qué es * * Se le permite cambiar? ¿Líneas de comando? ¿Archivos de parámetros? Por ejemplo, digamos que dije "Sí, puedes enganchar impresión", ¿cuál es el alcance de lo que podrías hacer? – Axeman
Puedo cambiar cualquier cosa en la biblioteca común. El usuario no debe necesitar ejecutar sus scripts de forma diferente, o debe pasar algo nuevo en la línea de comando. La secuencia final de datos en STDOUT y STDERR debe ser la misma que antes. –
¿Qué sucede con la salida original? ¿Puedes seguirlo y procesar desde allí? – user44511