next up previous contents index practicapracticaPP2moodleLHPmoodlepserratacpanmodulospauseperlgoogleetsiiullpcgull
Sig: Uso del Módulo de Sup: Módulos Ant: Práctica: Stash Err: Si hallas una errata ...

Carga Automática

En la mayor parte de los lenguajes de programación, si se llama a una subrutina que no existe se produce inmediatamente un error. Perl proporciona un medio para crear una rutina ``captura-llamadas'' para cada paquete, la cuál será llamada siempre que la rutina solicitada no exista. Su nombre debe ser AUTOLOAD. Los parámetros que se le pasan a dicha subrutina serán los mismos que se pasaron a la subrutina desaparecida. Cuando se invoca a AUTOLOAD, la variable (del paquete) $AUTOLOAD contiene el nombre de la rutina solicitada. De este modo es posible conocer que rutina intentaba invocar el programa usuario.

El siguiente ejemplo proporciona una interfase funcional a los comandos del sistema operativo:

$ cat -n Ejautoload.pm
 1  package Ejautoload;
 2
 3  sub AUTOLOAD {
 4    our $AUTOLOAD =~ s/.*:://; # suprimir el prefijo con el nombre del paquete
 5    my @result = `$AUTOLOAD @_`; # ejecutamos la funcion como un comando para
 6                           # la shell del sistema
 7    return @result;
 8  }
 9
10  sub import {
11    my $mypackage = shift;
12
13    my ($caller_package) = caller;
14    {
15      no strict 'refs';
16      for my $subroutinename (@_) {
17        *{$caller_package."::".$subroutinename} = \&{$subroutinename};
18      }
19    }
20  }
21
22  1;
Veamos el programa cliente:
$ cat -n command3.pl
     1  #!/usr/bin/perl -w -I.
     2  use Ejautoload('AUTOLOAD');
     3
     4  @files = ls("-l", "-t", "-r");
     5  print @files[-5..-1];
El programa obtiene el listado de ficheros en orden inverso de tiempos y muestra los cinco ficheros mas recientemente modificados:
$ ./command3.pl
-rwxr-xr-x   1 lhp lhp    156 2005-05-05 18:12 stash_ex.pl
-rw-r--r--   1 lhp lhp    330 2005-05-06 08:28 command.pl
-rw-r--r--   1 lhp lhp    330 2005-05-06 08:30 command2.pl
-rwxr-xr-x   1 lhp lhp    107 2005-05-06 11:06 command3.pl
-rw-r--r--   1 lhp lhp    475 2005-05-06 11:07 Ejautoload.pm

Veamos otro ejemplo:

Ejemplo 6.8.1   Tenemos en nuestro directorio un programa cliente jump.pl y un módulo Hops situado en el subdirectorio Modexample:
$ tree
.
|-- CVS
|   |-- Entries
|   |-- Repository
|   `-- Root
|-- Modexample
|   `-- Hops.pm
`-- jump.pl
Siguen los contenidos del fichero Modexample/Hops.pm:
package Modexample::Hops;

sub hop_along {
  my ($from, $to, $step) = @_;
  my $next = $from-$step;  # incializar contador
  my $closure_ref = sub {
    $next += $step;
    return if $next > $to;
    $_[0] =$next;
    return 1;
  };
  return $closure_ref;
}

sub import {
  print("Modexample::Hops::import: argumentos: ",join(", ", @_),"\n\n");
  return 1;
}

sub AUTOLOAD {
  @_ = map { "\"".$_."\""; } @_;
  print "Has llamado a $AUTOLOAD(",join(", ",@_),") y no existe!\n";
}

1;

El programa cliente jump.pl:

#!/usr/bin/perl -w -I.
use Modexample::Hops qw(one two);

$row = Modexample::Hops::hop_along 1, 5, 1;
while ($row->($r)) {
  $col = Modexample::Hops::hop_along 1, 5, 1;
  while ($col->($c)) {
    print("($r, $c)\t");
  }
  print "\n";
}

Modexample::Hops::noexisto("pepe", "eowyn", "eomer", "maria");

Y un ejemplo de ejecución:

$ jump.pl
Modexample::Hops::import: argumentos: Modexample::Hops, one, two

(1, 1)  (1, 2)  (1, 3)  (1, 4)  (1, 5)
(2, 1)  (2, 2)  (2, 3)  (2, 4)  (2, 5)
(3, 1)  (3, 2)  (3, 3)  (3, 4)  (3, 5)
(4, 1)  (4, 2)  (4, 3)  (4, 4)  (4, 5)
(5, 1)  (5, 2)  (5, 3)  (5, 4)  (5, 5)
Has llamado a Modexample::Hops::noexisto("pepe", "eowyn", "eomer", "maria") y no existe!


next up previous contents index practicapracticaPP2moodleLHPmoodlepserratacpanmodulospauseperlgoogleetsiiullpcgull
Sig: Uso del Módulo de Sup: Módulos Ant: Práctica: Stash Err: Si hallas una errata ...
Casiano Rodríguez León
2006-02-21