Las clausuras pueden ser un buen mecanismo para generar dinámicamente familias de funciones que se diferencian en algún parámetro.
En el siguiente ejemplo se quieren escribir funciones que faciliten la escritura de HTML, de manera que la llamada:
print HEAD("colores"), "¡Tenga ", red("cuidado"), "con esa ", green("luz!"),"\n", "¡Tenga ", RED("cuidado"), "con esa ", GREEN("luz!"),"\n", tail;produciría la salida:
lhp@nereida:~/Lperl/src$ colors3.pl <HTML> <HEAD> <TITLE>colores</TITLE> </HEAD> <BODY > ¡Tenga <FONT COLOR='red'>cuidado</FONT>con esa <FONT COLOR='green'>luz!</FONT> ¡Tenga <FONT COLOR='red'>cuidado</FONT>con esa <FONT COLOR='green'>luz!</FONT> </BODY> </HTML>
Este es el código:
lhp@nereida:~/Lperl/src$ cat -n colors3.pl 1 #!/usr/bin/perl -w 2 use strict; 3 4 my @colors = qw(red blue green yellow orange purple violet); 5 6 for my $name (@colors) { 7 no strict 'refs'; # permitir la manipulación de la tabla de símbolos 8 *$name = *{uc $name} = sub { "<FONT COLOR='$name'>@_</FONT>" }; 9 } 10 11 sub make_synonym { 12 my ($name, $sub) = @_; 13 die unless ($name =~ /[\w:]+/ && ref($sub) eq 'CODE'); 14 15 no warnings; 16 no strict 'refs'; 17 *$name = $sub; 18 } 19 20 sub tail { 21 return << 'COLA'; 22 </BODY> 23 </HTML> 24 COLA 25 } 26 make_synonym(TAIL => \&tail); 27 28 sub head { 29 my $title = shift; 30 return << "CABEZA"; 31 <HTML> 32 <HEAD> 33 <TITLE>$title</TITLE> 34 </HEAD> 35 <BODY > 36 CABEZA 37 } 38 make_synonym(HEAD => \&head); 39 40 ########### main ############## 41 print HEAD("colores"), 42 "¡Tenga ", red("cuidado"), "con esa ", green("luz!"),"\n", 43 "¡Tenga ", RED("cuidado"), "con esa ", GREEN("luz!"),"\n", 44 tail;
La clausura se forma en la línea 7 con la variable léxica $name
declarada en la línea 5. La subrutina que se crea ''recuerda''
el valor de $name
.
Se han usado typeglobs para instalar entradas en la tabla de símbolos
a la función tanto en minúsculas como en mayúsculas.
Las funciones head
y tail
producen HTML para la cabecera y la cola
usando documentos aqui (conocidos
como here-document o heredoc):
Casiano Rodríguez León