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