|
PAR::Intro - Introduction to Perl Archive Toolkit |
PAR::Intro - Introduction to Perl Archive Toolkit
# This is a presentation, not a module.
Note that a more extensive tutorial is now available online as http://aut.dyndns.org/par-tutorial/ and has superceded materials in this introduction.
par@perl.org
pp to compile the script...
% zip foo.par Hello.pm
% zip -r foo.par lib/ # grab all modules in lib/
% perl -MPAR=./foo.par -MHello
% perl -MPAR=./foo -MHello # the .par part is optional
% perl -MPAR -Ifoo.par -MHello
% perl -MPAR -Ifoo -MHello # ditto
pp to scan scripts and store dependencies as a PAR file:
% pp -p source.pl # makes 'source.par'
% pp -B -p source.pl # bundles core modules too
par.pl to run files from a Perl Archive:
% par.pl foo.par # looks for 'main.pl' by default
% par.pl foo.par test.pl # runs script/test.pl in foo.par
parl or parl.exe to run files from a Perl Archive:
% parl foo.par
% parl foo.par test.pl
pp utility can also generate binary executables:
% pp -o packed.exe source.pl # self-contained .exe
% packed.exe # runs anywhere with the same OS
# packs CGI + its dependencies, too
% pp -o packed.exe -M CGI source.pl
# turns one-liner into executable
% pp -o packed.exe -e 'print "Hi!"'
pp are almost identical to perlcc's
/lib/ # standard location
/arch/ # for creating from blib/
/i386-freebsd/ # i.e. $Config{archname}
/5.8.0/ # i.e. Perl version number
/5.8.0/i386-freebsd/ # combination of the two above
/ # casual packaging only
/script/ # standard location
/ # casual packaging only
/shlib/(5.8.0/)?(i386-freebsd/)?
/par/(5.8.0/)?(i386-freebsd/)?
=item *
Special files:
/MANIFEST # index of the PAR's contents
/SIGNATURE # digital signature(s)
/META.yml # dependency, license info, etc.
/Build.PL # self-contained installer
PAR::read_file($filename) to read file contents inside PAR
PAR::reload_libs() to reload modules within changed PARs
httpd.conf:
<VirtualHost *>
<IfDefine MODPERL2>
PerlModule Apache::ServerUtil
</IfDefine>
PerlModule Apache::PAR
PARDir /opt/myapp
PARFile /opt/myapp/myapp.par
</VirtualHost>
web.conf inside myapp.par:
Alias /myapp/static/ ##PARFILE##/
<Location /myapp/static>
SetHandler perl-script
PerlHandler Apache::PAR::Static
PerlAddVar PARStaticDirectoryIndex index.html
PerlSetVar PARStaticDefaultMIME text/html
</Location>
Alias /myapp/cgi-perl/ ##PARFILE##/
<Location /myapp/cgi-perl>
Options +ExecCGI
SetHandler perl-script
PerlHandler Apache::PAR::Registry
</Location>
pp's features
push @INC, \&my_sub;
sub my_sub {
my ($coderef, $filename) = @_; # $coderef is \&my_sub
open my $fh, "wget http://example.com/$filename |";
return $fh; # using remote modules, indeed!
}
open my $fh, '<', \($zip->memberNamed($filename)->contents);
return $fh;
Acme::use::strict::with::pride works:
# Force all modules used to use strict and warnings
open my $fh, "<", $filename or return;
my @lines = ("use strict; use warnings;\n", "#line 1 \"$full\"\n");
return ($fh, sub {
return 0 unless @lines;
push @lines, $_; $_ = shift @lines; return length $_;
});
# Return all contents line-by-line from the file inside PAR
my @lines = split /(?<=\n)/, $zip->memberNamed($filename)->contents;
return (sub { $_ = shift(@lines); return length $_ });
__END__ or __DATA__
eval the main.pl script
$DATACache{$file} = $1 if ($program =~ s/^__DATA__\n?(.*)//ms);
if (eval {require PerlIO::scalar; 1}) {
"use PerlIO::scalar".
" ( open(*DATA, '<:scalar', \\\$PAR::DATACache{'$key'}) ? () : () )";
}
elsif (eval {require IO::Scalar; 1}) {
# This will first load IO::Scalar, *then* tie the handles.
"use IO::Scalar".
" ( tie(*DATA, 'IO::Scalar', \\\$PAR::DATACache{'$key'}) ? () : () )";
}
else {
# only dies when it's used
"use PAR (tie(*DATA, 'PAR::_data') ? () : ())\n";
}
sub PAR::_data::TIEHANDLE { return bless({}, shift) }
sub PAR::_data::AUTOLOAD { die "Please install IO::Scalar first!\n" }
.so or .dll)
auto/ directories
bootstrap for XS loading
dl_findfile to locate the file
no strict 'refs'; no warnings 'redefine';
$bootstrap = \&DynaLoader::bootstrap;
$dl_findfile = \&DynaLoader::dl_findfile;
*{'DynaLoader::bootstrap'} = \&_bootstrap;
*{'DynaLoader::dl_findfile'} = \&_dl_findfile;
_bootstrap just checks if the library is in PARs
$bootstrap
_dl_findfile intercepts known filenames and return it
"PK\003\004"
pack('N') number of the total length of FILE and PAR sections
"\012PAR.pm\012"
FILE section in the previous slide is for
tempfile()
inflate()
http://www.autrijus.org/par-tutorial/
http://www.autrijus.org/par-intro/ (English version)
http://www.autrijus.org/par-intro.zh/ (Chinese version)
PAR, pp, par.pl, parl
the ex::lib::zip manpage, the Acme::use::strict::with::pride manpage
the App::Packer manpage, the Apache::PAR manpage, the CPANPLUS manpage, the Module::Install manpage
Autrijus Tang <autrijus@autrijus.org>
http://par.perl.org/ is the official PAR website. You can write to the mailing list at <par@perl.org>, or send an empty mail to <par-subscribe@perl.org> to participate in the discussion.
Please submit bug reports to <bug-par@rt.cpan.org>.
Copyright 2002, 2003 by Autrijus Tang <autrijus@autrijus.org>.
This document is free documentation; you can redistribute it and/or modify it under the same terms as Perl itself.
See http://www.perl.com/perl/misc/Artistic.html
|
PAR::Intro - Introduction to Perl Archive Toolkit |