El Operador Diamante y el Manejador de Ficheros ARGV

El operador diamante, denotado por <>, es un operador de entrada. Toma la entrada desde los ficheros cuyos nombres han sido pasados al programa en la línea de comandos:
>./miprog datos.dat file.txt x.log

El operador diamante, cuando sea llamado desde miprog tomara la entrada desde datos.dat, file.txt y x.log. Si el programa se llama sin argumentos leerá desde la entrada estándar.

Se puede usar el guión corto como sinónimo de leer desde la entrada estándar. El siguiente programa muestra los ficheros proveidos en la línea de comandos. Enumera las líneas y justifica los números de línea a la derecha según el valor de $width:

lhp@nereida:~/Lperl/src$ cat -n diamond.pl
 1  #!/usr/bin/perl -w
 2  use strict;
 3  use POSIX qw(ceil);
 4  use List::Util qw(max);
 5  my $width = shift if (@ARGV) and $ARGV[0] =~ m{^\d+$};
 6  $width = 2 unless $width;
 7  my @lines = map { (split /\s+/, `wc $_`)[1] } @ARGV; 
 8  @lines = map { ceil(log($_)) } @lines;
 9  $width = max( $width, @lines);
10  my $n = 1;
11  my $OLDARGV = "";
12  while (<>) {
13    if ($OLDARGV ne $ARGV) {
14      printf("FILE $ARGV\n");
15      $OLDARGV = $ARGV;
16      $n = 1;
17    }
18    printf("%${width}d %s", $n++, $_);
19  }
La variable $ARGV contiene el nombre del fichero actual. Veamos varias ejecuciones del programa:
lhp@nereida:~/Lperl/src$ diamond.pl 12 test.txt
FILE test.txt
           1 Welcome ...

lhp@nereida:~/Lperl/src$ diamond.pl test.txt which.pl
FILE test.txt
   1 Welcome ...
FILE which.pl
   1 #!/usr/bin/perl -w
   2
   3 $pattern = shift || '';
   4 $pattern =~ s{::}{/}g;
   5 #$pattern =~ s{$}{.pm};
   6 @dirs = @INC;
   7 #push @dirs, qw(
   8 #    /etc/perl
   9 #    /usr/local/lib/perl/5.8.4
  10 #    /usr/local/share/perl/5.8.4
  11 #    /usr/lib/perl5
  12 #    /usr/share/perl5
  13 #    /usr/lib/perl/5.8
  14 #    /usr/share/perl/5.8
  15 #    /usr/local/lib/site_perl
  16 #);
  17
  18 for (@dirs) {
  19   my $file = $_."/".$pattern.'.pm';
  20   print "$file\n" if (-e $file);
  21   $file = $_."/".$pattern.'.pod';
  22   print "$file\n" if (-e $file);
  23   $file = $_."/pod/".$pattern.'.pod';
  24   print "$file\n" if (-e $file);
  25 }

El operador diamante utiliza el array @ARGV el cual contiene la lista de argumentos pasados al programa en la línea de comandos. Cuandose usa el operador shift fuera de una subrutina, actúa por defecto sobre este array. Si al comienzo de nuestro programa modificamos el array @ARGV podemos alterar la conducta del operador diamante. El ejemplo que vemos a continuación modifica @ARGV de manera que el programa hará caso omiso de los argumentos pasados por el usuario.

lhp@nereida:~/Lperl/src$ cat -n diamond2.pl
     1  #!/usr/local/bin/perl -w
     2  use strict;
     3  my $n;
     4  @ARGV = qw#dummy.bk.1 dummy.bk.2#;
     5  while (<>) {
     6    print $n++." $_";
     7  }
Veamos un ejemplo de ejecución:
lhp@nereida:~/Lperl/src$ diamond.pl dummy.bk.1 dummy.bk.2
FILE dummy.bk.1
 1 ABCDEF
 2 ABCDEF
 3 ABCDEF
FILE dummy.bk.2
 1 ABCDEF
 2 ABCDEF
 3 ABCDEF
lhp@nereida:~/Lperl/src$ diamond2.pl 34 45 gethostbyname.pl
0 ABCDEF
1 ABCDEF
2 ABCDEF
3 ABCDEF
4 ABCDEF
5 ABCDEF
El manejador de ficheros especial usado por el operador diamante es conocido como ARGV . La expresión <> es un sinónimo de <ARGV>.

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