El siguiente programa rload.pl
carga el módulo Email::Valid
desde CPAN y lo usa para comprobar la validez de una dirección de email:
lhp@nereida:~/Lperl/src/testing$ perldoc -l Email::Valid No documentation found for "Email::Valid". lhp@nereida:~/Lperl/src/testing$ rload.pl 'casiano@ull.es' yes lhp@nereida:~/Lperl/src/testing$ rload.pl 'tutu.es' no
Este es el contenido del programa:
lhp@nereida:~/Lperl/src/testing$ cat -n rload.pl 1 #!/usr/bin/perl -w 2 #uses the web to retrieve Email::Valid, and does an example call 3 4 use strict; 5 use LWP::Simple; 6 7 scalar eval get('http://search.cpan.org/src/RJBS/Email-Valid-0.179/lib/Email/Valid.pm'); 8 9 print +(Email::Valid->address( -address => shift, 10 -mxcheck => 1 ) ? "yes\n" : "no\n");
Esta estrategia puede mejorarse construyendo un módulo que modifique la búsqueda
en @INC
para que los módulos sean descargados desde un site remoto:
pp2@nereida:~/src/perl/Module-Remote-LWP/examples$ cat ut2.pl #!/usr/bin/perl -w -I../lib/ use strict; use Module::Remote::LWP root => 'http://orion.pcg.ull.es/~casiano/cpan'; use Tintin::Trivial; Tintin::Trivial::hello();Cuando este programa se ejecuta accede al módulo
Tintinn::Trivial
pese
a que no esta disponible en la máquina local:
pp2@nereida:~/src/perl/Module-Remote-LWP/examples$ ut2.pl Hello from Tintin::Trivial
La estrategia se basa en una propiedad de require.
Sigue el extracto
(obtenido mediante el comando $ PERLDOC_PAGER=cat perldoc -oLaTeX -f require
)
de la documentación de require
relevante
a este asunto:
You can also insert hooks into the import facility, by putting directly
Perl code into the @INC
array. There are three forms of hooks: subroutine
references, array references and blessed objects.
Subroutine references are the simplest case. When the inclusion system walks through@INC
and encounters a subroutine, this subroutine gets called with two parameters, the first being a reference to itself, and the second the name of the file to be included (e.g. "Foo/Bar.pm"). The subroutine should return undef or a filehandle, from which the file to include will be read. If undef is returned, require will look at the remaining elements of@INC
.
If the hook is an array reference, its first element must be a subroutine reference. This subroutine is called as above, but the first parameter is the array reference. This enables to pass indirectly some arguments to the subroutine.
In other words, you can write:
push @INC, \&my_sub; sub my_sub { my ($coderef, $filename) = @_; # $coderef is \&my_sub ... }
or:
push @INC, [ \&my_sub, $x, $y, ... ]; sub my_sub { my ($arrayref, $filename) = @_; # Retrieve $x, $y, ... my @parameters = @$arrayref[1..$#$arrayref]; ... }
If the hook is an object, it must provide an INC method that will be called as above, the first parameter being the object itself. (Note that you must fully qualify the sub's name, as it is always forced into package main.) Here is a typical code layout:
# In Foo.pm package Foo; sub new { ... } sub Foo::INC { my ($self, $filename) = @_; ... }
# In the main program push @INC, new Foo(...);
Note that these hooks are also permitted to set the %INC entry corresponding to the files they have loaded. See %INC in perlvar.
El módulo que sigue muestra como implantar el proceso de carga remota:
pp2@nereida:~/src/perl/Module-Remote-LWP/lib/Module/Remote$ cat -n LWP.pm 1 package Module::Remote::LWP; 2 use strict; 3 use warnings; 4 5 our $VERSION = '0.02'; 6 7 use LWP::Simple; 8 9 my $URL; 10 11 sub import { 12 my $module = shift; 13 my %arg = @_; 14 15 die "Provide a root URL" unless defined $arg{root}; 16 $URL = $arg{root}; 17 18 } 19 20 sub new { 21 my $this = shift; 22 my $class = ref($this) || $this; 23 my %arg = @_; 24 25 my $self = bless {}, $class; 26 27 return $self; 28 } 29 30 sub Module::Remote::LWP::INC { 31 my ($self, $filename) = @_; 32 33 if ($filename =~ m{^[\w/\\]+\.pm$}) { 34 my $module = get("$URL/$_[1]") or return undef; 35 open my $fh, '<', \$module or return undef; 36 return $fh; 37 } 38 39 return undef; 40 } 41 42 BEGIN { 43 push (@INC, Module::Remote::LWP->new()); 44 } 45 46 1;
Casiano Rodríguez León