Contexto Booleano: Bucles con Lecturas de Directorios

En ocasiones es importante distinguir entre falsedad e indefinición, como en este ejemplo:

while ($file = <*>) {
  do_something($file);
}
En este código, en cada pasada del bucle el operador <*> produce un nuevo nombre de fichero del directorio actual. El nombre es asignado a $file. ¿Que ocurre si el nombre del fichero es "0"?. En tal caso el bucle debería tener una ''muerte'' prematura. La codificación correcta sería:
while (defined($file = <*>) {
   do_something($file);
}

Siguiendo la filosofía de ''ayudar'' al programador, las últimas versiones de Perl tiene el comportamiento ''esperado''. Esto es, detectan el uso en un while del glob e interpretan que "0" como nombre de fichero no es falso. Sin embargo en otro contexto, "0" si se interpreta como falso. Observe el siguiente ejemplo:

$ cat muerte_prematura2.pl
#!/usr/bin/perl -w

my $file;
my @a = ("uno","0","dos");

while ($file = shift @a) {
  do_something($file);
}

sub do_something {
  print "$file\n";
}
Al ejecutar obtenemos:
$ ./muerte_prematura2.pl
uno

Esta modificación de la evaluación ''normal'' de una expresión en un contexto lógico/booleano no es (del todo) privilegio exclusivo de Perl. El programador puede conseguir un efecto similar usando el módulo Contextual::Return de Damian Conway, el cual permite crear variables contextuales multitipo con mas de dos tipos:

lhp@nereida:~/Lperl/src/testing$ cat -n context1.pl
 1  #!/usr/local/bin/perl -w
 2  use strict;
 3  use Contextual::Return;
 4
 5  my $x = BOOL { 0 } NUM { 3.14 } STR { "pi" };
 6
 7  unless ($x) { warn "¡El famoso número $x (".(0+$x).") pasa a ser falso!\n" } # executed!
lhp@nereida:~/Lperl/src/testing$ context1.pl
¡El famoso número pi (3.14) pasa a ser falso!

Casiano Rodríguez León
Licencia de Creative Commons
Principios de Programación Imperativa, Funcional y Orientada a Objetos Una Introducción en Perl/Una Introducción a Perl
por Casiano Rodríguez León is licensed under a Creative Commons Reconocimiento 3.0 Unported License.

Permissions beyond the scope of this license may be available at http://campusvirtual.ull.es/ocw/course/view.php?id=43.
2012-06-19