El módulo PAR permite usar ficheros .zip que siguen un formato denominado Perl Archives.
En una primera aproximación podemos decir que un fichero .par es un fichero zip que contiene módulos.
Supongamos que estoy en una máquina (orion
) que
tiene instalado el módulo Parse::Eyapp:
casiano@orion:/usr/local/share/perl/5.8.8$ perldoc -l Parse::Eyapp /usr/local/share/perl/5.8.8/Parse/Eyapp.pmPara crear un fichero .par basta con llamar a zip:
casiano@orion:/usr/local/share/perl/5.8.8$ zip -r /tmp/orionparse.par Parse/ updating: Parse/ (stored 0%) updating: Parse/Eyapp.pm (deflated 69%) updating: Parse/Eyapp/ (stored 0%) updating: Parse/Eyapp/Lalr.pm (deflated 74%) updating: Parse/Eyapp/YATW.pm (deflated 64%) updating: Parse/Eyapp/Treeregexp.pm (deflated 77%) updating: Parse/Eyapp/Parse.pm (deflated 78%) updating: Parse/Eyapp/Scope.pm (deflated 61%) updating: Parse/Eyapp/Options.pm (deflated 63%) updating: Parse/Eyapp/Output.pm (deflated 60%) updating: Parse/Eyapp/Node.pm (deflated 72%) updating: Parse/Eyapp/Grammar.pm (deflated 71%) updating: Parse/Eyapp/Driver.pm (deflated 70%) updating: Parse/Eyapp/Base.pm (deflated 52%) updating: Parse/Eyapp/_TreeregexpSupport.pm (deflated 50%)La opción
-r
hace que zip recorra la estructura de directorios
recursivamente.
Ahora transferimos el fichero /tmp/orionparse.par a una
máquina (nereida
) en la cual no esta instalado
Parse::Eyapp:
lhp@nereida:~/Lperl/src$ scp orion:/tmp/orionparse.par . orionparse.par 100% 105KB 105.0KB/s 00:00Utilizando PAR podemos cargar el módulo Parse::Eyapp desde el fichero /tmp/orionparse.par
lhp@nereida:~/Lperl/src$ perl -wde 0 main::(-e:1): 0 DB<1> use PAR 'orionparse.par' DB<2> use Parse::Eyapp DB<3> print $Parse::Eyapp::VERSION 1.082 DB<4>Tambien podemos hacerlo con un one-liner:
lhp@nereida:~/Lperl/src$ perl -MPAR=orionparse.par -MParse::Eyapp -e 'print "$Parse::Eyapp::VERSION\n"' 1.082
Es posible añadir ficheros ejecutables a un fichero .par.
El módulo Parse::Eyapp
viene con el ejecutable
eyapp
. Añadámoslo al fichero .par:
casiano@orion:/usr/local/share/perl/5.8.8$ which eyapp /usr/local/bin/eyapp casiano@orion:/usr/local/share/perl/5.8.8$ cd /usr/local/bin/ casiano@orion:/usr/local/bin$ zip -r /tmp/orionparse.par eyapp adding: eyapp (deflated 59%) casiano@orion:/usr/local/bin$
Transferimos de nuevo el fichero .par a la máquina nereida:
lhp@nereida:~/Lperl/src$ scp orion:/tmp/orionparse.par . orionparse.par 100% 108KB 108.0KB/s 00:00Siempre es posible listar los ficheros que forman parte de una distribución usando unzip con la opción
-l
:
lhp@nereida:~/Lperl/src$ unzip -l orionparse.par Archive: orionparse.par Length Date Time Name -------- ---- ---- ---- 0 11-02-07 12:40 Parse/ 135815 11-01-07 13:14 Parse/Eyapp.pm 0 11-02-07 12:40 Parse/Eyapp/ 29574 09-17-07 16:38 Parse/Eyapp/Lalr.pm 8178 09-17-07 16:17 Parse/Eyapp/YATW.pm 51402 11-01-07 13:17 Parse/Eyapp/Treeregexp.pm 52766 11-01-07 13:17 Parse/Eyapp/Parse.pm 11069 09-17-07 16:40 Parse/Eyapp/Scope.pm 6314 09-17-07 16:39 Parse/Eyapp/Options.pm 8826 09-17-07 17:53 Parse/Eyapp/Output.pm 23784 09-17-07 16:17 Parse/Eyapp/Node.pm 13832 09-17-07 16:38 Parse/Eyapp/Grammar.pm 17865 11-01-07 13:05 Parse/Eyapp/Driver.pm 3673 09-17-07 16:37 Parse/Eyapp/Base.pm 3296 09-17-07 16:40 Parse/Eyapp/_TreeregexpSupport.pm 7102 11-02-07 12:40 eyapp 0 07-10-08 10:22 Math/ 0 08-08-08 12:08 Math/Prime/ 5635 05-14-08 15:30 Math/Prime/XS.pm -------- ------- 379131 19 filesEl programa par.pl permite ejecutar ficheros en un archivo .par:
lhp@nereida:~/Lperl/src$ par.pl orionparse.par eyapp -V This is Parse::Eyapp version 1.082.Por defecto par.pl busca por un ejecutable con nombre
main.pl
.
También puedo extraer el ejecutable:
lhp@nereida:~/Lperl/src/tmp$ unzip orionparse.par eyapp Archive: orionparse.par inflating: eyappy a continuación ejecutarlo usando el módulo PAR:
lhp@nereida:~/Lperl/src/tmp$ perl -MPAR=orionparse.par eyapp -V This is Parse::Eyapp version 1.082.
PAR soporta la carga de módulos XS (véase perlxs). XS es un formato para la descripción de interfases entre código C y código Perl. Veamos un ejemplo. La sesión se inicia como administrador arrancando cpan para a continuación descargar el módulo Math::Prime::XS el cual, como su nombre indica, tiene partes escritas en C:
root@orion:~# cpan cpan shell -- CPAN exploration and modules installation (v1.7602) ReadLine support enabledEl comando
look Math::Prime::XSque emitimos a continuación indica que queremos abrir una shell en el directorio de la distribución de Math::Prime::XS. Si el módulo no está actualizado,
cpan
procederá a descargarse
la última versión antes de abrir una shell:
cpan> look Math::Prime::XS CPAN: Storable loaded ok Going to read /root/.cpan/Metadata Database was generated on Fri, 08 Aug 2008 03:02:59 GMT CPAN: LWP::UserAgent loaded ok Fetching with LWP: ftp://perl.di.uminho.pt/pub/CPAN/authors/01mailrc.txt.gz Going to read /root/.cpan/sources/authors/01mailrc.txt.gz CPAN: Compress::Zlib loaded ok Fetching with LWP: ftp://perl.di.uminho.pt/pub/CPAN/modules/02packages.details.txt.gz Going to read /root/.cpan/sources/modules/02packages.details.txt.gz Database was generated on Thu, 21 Aug 2008 02:03:21 GMT Fetching with LWP: ftp://perl.di.uminho.pt/pub/CPAN/modules/03modlist.data.gz Going to read /root/.cpan/sources/modules/03modlist.data.gz Going to write /root/.cpan/Metadata Running look for module Math::Prime::XS Trying to open a subshell in the build directory... CPAN: Digest::MD5 loaded ok Checksum for /root/.cpan/sources/authors/id/S/SC/SCHUBIGER/Math-Prime-XS-0.20.tar.gz ok Scanning cache /root/.cpan/build for sizes Math-Prime-XS-0.20/ Math-Prime-XS-0.20/Changes Math-Prime-XS-0.20/lib/ Math-Prime-XS-0.20/lib/Math/ Math-Prime-XS-0.20/lib/Math/Prime/ Math-Prime-XS-0.20/lib/Math/Prime/XS.pm Math-Prime-XS-0.20/ppport.h Math-Prime-XS-0.20/MANIFEST Math-Prime-XS-0.20/XS.xs Math-Prime-XS-0.20/t/ Math-Prime-XS-0.20/t/pod-coverage.t Math-Prime-XS-0.20/t/calc_primes.t Math-Prime-XS-0.20/t/pod.t Math-Prime-XS-0.20/t/00-load.t Math-Prime-XS-0.20/INSTALL Math-Prime-XS-0.20/Build.PL Math-Prime-XS-0.20/META.yml Math-Prime-XS-0.20/Makefile.PL Math-Prime-XS-0.20/README Removing previously used /root/.cpan/build/Math-Prime-XS-0.20 Working directory is /root/.cpan/build/Math-Prime-XS-0.20Aunque la sesión ha sido arrancada como
root
podría haberla hecho
como un usuario ordinario. El único objetivo era descargar la distribución
de Math::Prime::XS
y posicionarse en el correspondiente directorio.
root@orion:~/.cpan/build/Math-Prime-XS-0.20# ls -l total 204 -r--r--r-- 1 csegura csegura 786 2008-05-14 15:30 Build.PL -r--r--r-- 1 csegura csegura 1445 2008-05-14 15:30 Changes -r--r--r-- 1 csegura csegura 290 2008-05-14 15:30 INSTALL drwxr-xr-x 3 csegura csegura 4096 2008-05-14 15:30 lib -r--r--r-- 1 csegura csegura 498 2008-05-14 15:30 Makefile.PL -r--r--r-- 1 csegura csegura 172 2008-05-14 15:30 MANIFEST -r--r--r-- 1 csegura csegura 560 2008-05-14 15:30 META.yml -r--r--r-- 1 csegura csegura 154956 2008-05-14 15:30 ppport.h -r--r--r-- 1 csegura csegura 5033 2008-05-14 15:30 README drwxr-xr-x 2 csegura csegura 4096 2008-05-14 15:30 t -r--r--r-- 1 csegura csegura 4843 2008-05-14 15:30 XS.xsConstruimos la distribución siguiendo el procedimiento habitual:
root@orion:~/.cpan/build/Math-Prime-XS-0.20# perl Makefile.PL Checking if your kit is complete... Looks good Writing Makefile for Math::Prime::XS root@orion:~/.cpan/build/Math-Prime-XS-0.20# make cp lib/Math/Prime/XS.pm blib/lib/Math/Prime/XS.pm /usr/bin/perl /usr/local/share/perl/5.8.8/ExtUtils/xsubpp \ -typemap /usr/share/perl/5.8/ExtUtils/typemap \ XS.xs > XS.xsc && mv XS.xsc XS.c cc -c -D_REENTRANT -D_GNU_SOURCE -DTHREADS_HAVE_PIDS -DDEBIAN -fno-strict-aliasing -pipe \ -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -O2 \ -DVERSION=\"0.20\" -DXS_VERSION=\"0.20\" -fPIC "-I/usr/lib/perl/5.8/CORE" XS.c Running Mkbootstrap for Math::Prime::XS () chmod 644 XS.bs rm -f blib/arch/auto/Math/Prime/XS/XS.so cc -shared -L/usr/local/lib XS.o -o blib/arch/auto/Math/Prime/XS/XS.so chmod 755 blib/arch/auto/Math/Prime/XS/XS.so cp XS.bs blib/arch/auto/Math/Prime/XS/XS.bs chmod 644 blib/arch/auto/Math/Prime/XS/XS.bs Manifying blib/man3/Math::Prime::XS.3pmEl aspecto mas notable de esta construcción es que se ha llamado al compilador de
C
. Las opciones pasadas al compilador han sido las mismas
que se usaron en la instalación de Perl en la plataforma en uso.
Ahora cambiamos al directorio de construcción blib
:
root@orion:~/.cpan/build/Math-Prime-XS-0.20# cd blibEn el directorio
arch
está la librería .so
(shared object).
En el directorio lib
esta el módulo Perl .pm
que contiene la interfaz Perl a las funciones C:
root@orion:~/.cpan/build/Math-Prime-XS-0.20/blib# tree . |-- arch | `-- auto | `-- Math | `-- Prime | `-- XS | |-- XS.bs | `-- XS.so |-- bin |-- lib | |-- Math | | `-- Prime | | `-- XS.pm | `-- auto | `-- Math | `-- Prime | `-- XS |-- man1 |-- man3 | `-- Math::Prime::XS.3pm `-- scriptPara construir el fichero
.par
usamos zip
añadiendo los
directorios arch
y lib
.
los contenidos de
root@orion:~/.cpan/build/Math-Prime-XS-0.20/blib# zip -r /tmp/primexs.par arch/ lib/ adding: arch/ (stored 0%) adding: arch/.exists (stored 0%) adding: arch/auto/ (stored 0%) adding: arch/auto/Math/ (stored 0%) adding: arch/auto/Math/Prime/ (stored 0%) adding: arch/auto/Math/Prime/XS/ (stored 0%) adding: arch/auto/Math/Prime/XS/.exists (stored 0%) adding: arch/auto/Math/Prime/XS/XS.so (deflated 59%) adding: arch/auto/Math/Prime/XS/XS.bs (stored 0%) adding: lib/ (stored 0%) adding: lib/Math/ (stored 0%) adding: lib/Math/Prime/ (stored 0%) adding: lib/Math/Prime/.exists (stored 0%) adding: lib/Math/Prime/XS.pm (deflated 59%) adding: lib/auto/ (stored 0%) adding: lib/auto/Math/ (stored 0%) adding: lib/auto/Math/Prime/ (stored 0%) adding: lib/auto/Math/Prime/XS/ (stored 0%) adding: lib/auto/Math/Prime/XS/.exists (stored 0%) root@orion:~/.cpan/build/Math-Prime-XS-0.20/blib#Es habitual que un fichero
.par
este fundamentalmente constituído por
los contenidos del directorio blib/
construido
a partir de una distribución CPAN.
Ahora transferimos el fichero /tmp/primexs.par
a una
máquina que carece de los módulos en dicho fichero, pero
que es binario-compatible con la máquina en la que se realizó
la construcción:
lhp@nereida:~/Lperl/src$ perldoc -l Math::Prime::XS No documentation found for "Math::Prime::XS".Después de la transferencia estamos en condiciones de usar el módulo Math::Prime::XS utilizando via PAR la distribucion
primexs.par
:
lhp@nereida:~/Lperl/src$ scp orion:/tmp/primexs.par . primexs.par 100% 11KB 11.4KB/s 00:00 lhp@nereida:~/Lperl/src$ vi prime3.pl lhp@nereida:~/Lperl/src$ cat -n prime3.pl 1 #!/usr/bin/perl -I../lib -w 2 use PAR "primexs.par"; 3 use Math::Prime::XS qw{:all}; 4 5 @all_primes = primes(9); 6 print "@all_primes\n"; 7 8 @range_primes = primes(4, 9); 9 print "@range_primes\n";El programa se ejecuta sin errores produciendo la salida esperada:
lhp@nereida:~/Lperl/src$ prime3.pl 2 3 5 7 5 7Por supuesto, el éxito de esta ejecución depende de la compatibilidad binaria de ambas plataformas (
orion
y nereida
)
Es posible utilizar ficheros PAR cuya localización está en una máquina remota:
use PAR "http://orion.pcg.ull.es/~casiano/primexs.par";En este escenario PAR cargará los módulos solicitados desde el repositorio PAR situado en
http://foo/bar/
.
Por supuesto debemos el fichero .par
deberá estar en la máquina remota (en el ejemplo
que sigue orion
). Copiamos el .par
construido anteriormente en el directorio
que contiene nuestros HTML publicos:
casiano@orion:~/public_html$ cp /tmp/primexs.par . casiano@orion:~/public_html$ pwd /home/casiano/public_html casiano@orion:~/public_html$ ls -ltr | tail -1 -rw-r--r-- 1 casiano casiano 11685 2008-08-23 12:57 primexs.parAhora podemos ejecutar en la máquina cliente
nereida
un programa que hace uso
del repositorio situado en orion
:
lhp@nereida:~/Lperl/src$ cat -n prime4.pl 1 #!/usr/bin/perl -I../lib -w 2 use PAR "http://orion.pcg.ull.es/~casiano/primexs.par"; 3 use Math::Prime::XS qw{:all}; 4 5 @all_primes = primes(9); 6 print "@all_primes\n"; 7 8 @range_primes = primes(4, 9); 9 print "@range_primes\n";El programa se ejecuta normalmente:
lhp@nereida:~/Lperl/src$ prime4.pl 2 3 5 7 5 7