Hay varias maneras de manejar algo similar a una macro de C en Perl: un filtro de fuente, una subrutina, Template :: Toolkit o usar funciones en su editor de texto.
Filtros Fuente
Si tienes que tienen una macro C/CPP estilo preprocesador, es posible escribir una en Perl (o, en realidad, cualquier idioma) utilizando una compilación previa source filter. Puede escribir clases de Perl bastante simples a complejas que operan en el texto de su código fuente y realizar transformaciones antes de que el código vaya al compilador de Perl. Incluso puede ejecutar su código Perl directamente a través de un preprocesador CPP para obtener el tipo exacto de macroexpansiones que obtiene en C/CPP usando Filter::CPP.
Damian Conway's Filter::Simple es parte de la distribución de núcleos Perl.Con Filter :: Simple, podría escribir fácilmente un módulo simple para realizar la macro que está describiendo. Un ejemplo:
package myopinion;
# save in your Perl's @INC path as "myopinion.pm"...
use Filter::Simple;
FILTER {
s/Hogs/Pigs/g;
s/Hawgs/Hogs/g;
}
1;
A continuación, un archivo Perl:
use myopinion;
print join(' ',"Hogs", 'Hogs', qq/Hawgs/, q/Hogs/, "\n");
print "In my opinion, Hogs are Hogs\n\n";
Salida:
Pigs Pigs Hogs Pigs
In my opinion, Pigs are Pigs
Si reescribiste el filtro para hacer la sustitución de la macro deseada, Filtro :: Simple debería funcionar bien Filter :: Simple puede restringirse a partes de su código para crear subestaciones, como la parte ejecutable pero no la parte POD; solo en cuerdas; solo en código
En mi experiencia, los filtros de fuente no se usan ampliamente. En su mayoría los he visto con intentos poco convincentes de cifrar el código fuente de Perl o el humorístico Perl obfuscators. En otras palabras, sé que se puede hacer de esta manera, pero personalmente no sé lo suficiente sobre ellos como para recomendarlos o decirles que no los utilicen.
subrutinas
Sinan Unur openex subroutine es una buena manera de lograr esto. Sólo añadiré que un lenguaje común más antiguo que se pueden ver consiste en pasar una referencia a un typeglob así:
sub opensesame {
my $fn=shift;
local *FH;
return open(FH,$fn) ? *FH : undef;
}
$fh=opensesame('> /tmp/file');
Leer perldata de por qué es así ...
Template Toolkit
Template::Toolkit se puede utilizar para procesar el código fuente de Perl. Por ejemplo, podría escribir una plantilla a lo largo de las líneas de:
[% fw(fp, outfile) %]
en ejecución que a través de la plantilla :: Toolkit puede dar lugar a la expansión y la sustitución de:
open my $FP, '>', $outfile or die "$outfile could not be opened for writing:$!";
Plantilla :: Toolkit se utiliza con mayor frecuencia para separar el HTML desordenado y otro código de presentación del código de la aplicación en aplicaciones web. Template :: Toolkit se desarrolla muy activamente y está bien documentado. Si su único uso es un macro del tipo que está sugiriendo, puede ser excesivo.
editores de texto
Chas. Owens tiene un method usando Vim. Uso BBEdit y podría escribir fácilmente una Fábrica de Textos para reemplazar el esqueleto de un abierto con el abierto preciso y evolutivo que quiero usar. Alternativamente, puede colocar una plantilla de finalización en su directorio "Recursos" en la carpeta "Perl". Estos esqueletos de finalización se utilizan cuando presiona la serie de teclas que define. Casi cualquier editor serio tendrá una funcionalidad similar.
Con BBEdit, incluso puede usar el código Perl en su lógica de reemplazo de texto. Yo uso Perl::Critic de esta manera. Puede usar Template::Toolkit
dentro de BBEdit para procesar las macros con cierta inteligencia. Se puede configurar para que la plantilla no cambie el código fuente hasta que genere una versión para probar o compilar; el editor esencialmente está actuando como un preprocesador.
Dos posibles problemas con el uso de un editor de texto. Primero es una transformación de una vía/una vez.Si desea cambiar lo que hace su "macro", no puede hacerlo, ya que el texto anterior de "macro" ya se utilizó. Tienes que cambiarlos manualmente. El segundo problema potencial es que si usa un formulario de plantilla, no puede enviar la versión de macro del código fuente a otra persona porque el preprocesamiento se está realizando dentro del editor.
¡No haga esto!
Si escribe perl -h
para obtener parámetros de comando válida, una opción que puede ver es:
-P run program through C preprocessor before compilation
tentador! Sí, puede ejecutar su código Perl a través del preprocesador C y expandir las macros estilo C y tener #defines
. Deja esa pistola; alejarse; no lo hagas Hay muchas incompatibilidades de plataforma e incompatibilidades de lenguaje.
Usted recibe cuestiones como esta:
#!/usr/bin/perl -P
#define BIG small
print "BIG\n";
print qq(BIG\n);
Lienzo:
BIG
small
En Perl 5.12 el interruptor -P
se ha eliminado ...
Conclusión
Los la solución más flexible aquí es solo escribir una subrutina. Todo su código es visible en la subrutina, se cambia fácilmente y es una llamada más corta. Ningún inconveniente real aparte de la legibilidad de su código potencialmente.
Template :: Toolkit es ampliamente utilizado. Puede escribir reemplazos complejos que actúan como macros o incluso más complejos que las macros de C. Si su necesidad de macros vale la curva de aprendizaje, use Template :: Toolkit.
Para casos muy simples, utilice las transformaciones de una vía en un editor.
Si realmente quiere macros de estilo C, puede usar Filter::CPP. Esto puede tener las mismas incompatibilidades que el interruptor perl -P
. No puedo recomendar esto; solo aprende el camino de Perl.
Si desea ejecutar Perl one liners y Perl regexs contra su código antes de compilar, use Filter :: Simple.
Y no use el interruptor -P
. No puede en las versiones más nuevas de Perl de todos modos.
Yo diría "no puedo" en lugar de "no puedo" porque quién sabe cuál es el estado actual de ese archivo; solo sabemos cuál era el estado cuando intentamos abrirlo (de ahí el tiempo pasado). Por supuesto, eso es una suficiencia sin sentido. Podrías decir "Bang for $ filename: $!" Con la misma facilidad. –
Ah, y 'corelist' dice que Perl 5.10.1 fue la primera versión con' autodie' en el núcleo y el [delta] (http://perldoc.perl.org/perl5101delta.html#New- Modules- and -Pragmata) respalda eso. –
@Chas - editado. @Sinan - +1 por "$!". Los mensajes de error legibles y accionables son un arte a menudo infravalorado en el desarrollo de software. – DVK