next up previous contents index practicapracticaPP2moodleLHPmoodlepserratacpanmodulospauseperlgoogleetsiiullpcgull
Sig: Práctica: Viejos y Grandes Sup: Directorios Ant: Acceso mediante Operadores Err: Si hallas una errata ...


Acceso Mediante glob

El operador glob permite la expansión de los comodines de la shell. Asi en una expresión como:
my @all_files = glob "*";
la variable all_files guarda ordenados alfabéticamente la lista de los nombres de los ficheros en el directorio actual.

Es posible, como indica el siguiente ejemplo utilizar varios patrones separados por espacios.

my @including_hidden = ".* *";

Usar glob es mas eficiente y mas portable que enviar el requerimiento a la shell del sistema usando backticks (como por ejemplo en `ls .*`).

Cuando en el operador de lectura <> el argumento es una cadena glob de descripción de ficheros con comodines, el globbing se produce automáticamente:

my $dir = "/home/casiano/";
my $dir_files = <$dir/* $dir/.*>;

También puede hacerse en un contexto de lista:

DB<1> @modules = <*.pm>
DB<2> p "@modules"
A.pm Abstract.pm B.pm C.pm DandC.pm Frac.pm Fraction.pm

En general, si el identificador entre ángulos es un filehandler, Perl hace un acceso a través de él, en caso contrario interpreta que se trata de una operación de globbing. Esto es asi, incluso si la lectura hace uso de un manipulador indirecto que use variables intermedias. Véase el siguiente ejemplo:

  DB<1> $f = 'yapp'
  DB<2> @f = <$f/*.yp>
  DB<3> p "@f"
yapp/aSb.yp yapp/Autoaction1.yp yapp/Calc.yp yapp/Calc2.yp 
  DB<4> open F, 'logic.pl'
  DB<5> $x = F
  DB<6> @x = <$x>
  DB<7> p "@x"
#!/usr/bin/perl -w
 $a = 4; $b = "hola"; $c = 0; $d = "";
 print $a && $b,"\n";
 print $a and $b,"\n";
 print ($a and $b),"\n";

Obsérve que en un bucle for (list) el argumento list se evalúa en un contexto de lista.

my $bytes = 0;
for (<*.c>) { $bytes += -s }
En este código, la lectura del directorio <*.c> se produce en un contexto de lista. Por ello el directorio completo es leído y produce una lista con todos los nombres de ficheros *.c existentes en el directorio actual. El subsecuente proceso iterativo acumula en $bytes el tamaño de los ficheros *.c.

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 tendrá una ``muerte'' prematura. La codificación correcta sería:
while (defined($file = <*>) {
   do_something($file);
}
Sin embargo, 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


next up previous contents index practicapracticaPP2moodleLHPmoodlepserratacpanmodulospauseperlgoogleetsiiullpcgull
Sig: Práctica: Viejos y Grandes Sup: Directorios Ant: Acceso mediante Operadores Err: Si hallas una errata ...
Casiano Rodríguez León
2006-02-21