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