Clausuras y Generación de Funciones Similares

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
2009-10-04