PAR(3)
π PAR π β the Perl Archive Toolkit
okay so bestie, you found it: PAR(3), the User Contributed Perl Documentation page for the Perl Archive Toolkit. She's a whole vibe. Let's get into it π¦
β¨ SYNOPSIS β¨
(Real talk first: if you wanna make an executable that has all your modules, scripts and data files inside it, go look at the pp utility instead, okay? pp used to live inside the PAR distribution but now it ships as part of the PAR::Packer distribution instead. Not our problem anymore π
)
The examples below are assuming you've got a foo.par file in Zip format. Slay.
To use Hello.pm from ./foo.par:
% perl -MPAR=./foo.par -MHello
% perl -MPAR=./foo -MHello # the .par part is optional
Same energy, but we search for foo.par in @INC:
% perl -MPAR -Ifoo.par -MHello
% perl -MPAR -Ifoo -MHello # ditto
The following paths inside the PAR file get searched:
/lib/
/arch/
/i386-freebsd/ # i.e. $Config{archname}
/5.8.0/ # i.e. $Config{version}
/5.8.0/i386-freebsd/ # both of the above
/
PAR files can also (recursively, yes, recursively) contain other PAR files. Everything under these paths counts as a PAR file and gets searched too:
/par/i386-freebsd/ # i.e. $Config{archname}
/par/5.8.0/ # i.e. $Config{version}
/par/5.8.0/i386-freebsd/ # both of the above
/par/
Wanna run script/test.pl or test.pl from foo.par?
% perl -MPAR foo.par test.pl # only when $0 ends in '.par'
BUT. If the .par archive contains either script/main.pl or main.pl, then that one gets used instead:
% perl -MPAR foo.par test.pl # runs main.pl; @ARGV is 'test.pl'
Using it inside a program:
use PAR 'foo.par';
use Hello; # reads within foo.par
# PAR::read_file() returns a file inside any loaded PARs
my $conf = PAR::read_file('data/MyConfig.yaml');
# PAR::par_handle() returns an Archive::Zip handle
my $zip = PAR::par_handle('foo.par')
my $src = $zip->memberNamed('lib/Hello.pm')->contents;
You can use wildcard characters too, periodt:
use PAR '/home/foo/*.par'; # loads all PAR files in that directory
Since version 0.950, there's also a different syntax for loading .par archives:
use PAR { file => 'foo.par' }, { file => 'otherfile.par' };
Why would you do that? Because you can also do this:
use PAR { file => 'foo.par, fallback => 1 };
use Foo::Bar;
Foo::Bar gets searched in the system libs first, and only loaded from foo.par if it wasn't found! the way that worksβ¦ π€
use PAR { file => 'foo.par', run => 'myscript' };
This loads foo.par as usual and then executes the script/myscript file from the archive. Heads up: your program will not regain control. When script/myscript exits, so does your main program. To make this more useful you can defer it to runtime (otherwise equivalent):
require PAR;
PAR->import( { file => 'foo.par', run => 'myscript' } );
If you have PAR::Repository::Client installed, you can do this:
use PAR { repository => 'http://foo/bar/' };
use Module; # not locally installed!
And PAR will fetch any modules you don't have from the specified PAR repository. For the deets on how that works, peek at the SEE ALSO section below π. Instead of a URL or a local path, you can construct a PAR::Repository::Client object manually and hand that to PAR. If you specify the install => 1 option in the use PAR line above, the distribution containing Module will be permanently installed on your system. (use PAR { repository => 'http://foo/bar', install => 1 };)
Also there's an upgrade => 1 option that checks for upgrades in the repository in addition to installing. Please note that an upgraded version of a module is only loaded on the next run of your application.
Adding the dependencies => 1 option enables PAR::Repository::Client's static dependency resolution (that's PAR::Repository::Client 0.23 and up).
Finally β and this is iconic β you can combine the run and repository options to run an application directly from a repository! (And you can add the install option too.)
use PAR { repository => 'http://foo/bar/', run => 'my_app' };
# Will not reach this point as we executed my_app,
πΈ DESCRIPTION πΈ
This module lets you use special zip files, called Perl Archives, as libraries from which Perl modules can be loaded.
It supports loading XS modules by overriding DynaLoader bootstrapping methods; it writes the shared object file to a temporary file at the time it's needed. lowkey genius behavior
A .par file is mostly just a zip of the blib/ directory after the build process of a CPAN distribution. Wanna generate a .par yourself? All you have to do is compress the modules under arch/ and lib/, like:
% perl Makefile.PL
% make
% cd blib
% zip -r mymodule.par arch/ lib/
Afterward you can just use mymodule.par anywhere in your @INC, use PAR, and it will Just Work. Support for generating .par files is going to be in the next (beyond 0.2805) release of Module::Build.
For convenience, you can set the PERL5OPT environment variable to -MPAR to enable PAR processing globally (the overhead is small if not used); setting it to -MPAR=/path/to/mylib.par will load a specific PAR file. Alternatively, consider using the par.pl utility bundled with the PAR::Packer distribution, or using the self-contained parl utility which is also distributed with PAR::Packer on machines without PAR.pm installed. π«Ά
Note that self-containing scripts and executables created with par.pl and pp may also be used as .par archives:
% pp -o packed.exe source.pl # generate packed.exe (see PAR::Packer)
% perl -MPAR=packed.exe other.pl # this also works
% perl -MPAR -Ipacked.exe other.pl # ditto
Please see SYNOPSIS for most typical use cases. π
π NOTES π
Settings in META.yml packed inside the PAR file may affect PAR's operation. For example, pp provides the -C (--clean) option to control the default behavior of temporary file creation.
Currently, pp-generated PAR files may attach four PAR-specific attributes in META.yml:
par:
clean: 0 # default value of PAR_CLEAN
signature: '' # key ID of the SIGNATURE file
verbatim: 0 # was packed prerequisite's PODs preserved?
version: x.xx # PAR.pm version that generated this PAR
User-defined environment variables, like PAR_GLOBAL_CLEAN, always override the ones set in META.yml. The algorithm for generating the caching/temporary directory goes like this:
- If
PAR_GLOBAL_TEMPis specified, use it as the cache directory for extracted libraries, and do not clean it up after execution. - If
PAR_GLOBAL_TEMPis not set, butPAR_GLOBAL_CLEANis specified, setPAR_GLOBAL_TEMPtoTEMP/par-USERHEX/temp-PID/, cleaning it after execution. - If both are not set, use
TEMP/par-USERHEX/cache-HASH/as thePAR_GLOBAL_TEMP, reusing any existing files inside.
Here is a description of the variables in those previous paths π
TEMPis a temporary directory, which can be set via$ENV{PAR_GLOBAL_TMPDIR},$ENV{TMPDIR},$ENV{TEMPDIR},$ENV{TEMP}or$ENV{TMP}, in that order of priority. If none of those are set,C:\TEMP,/tmpare checked. If neither of them exists,.is used.USERHEXis derived from the user name, orSYSTEMif none can be found. On Win32, this is$Win32::LoginName. On Unix, this is$ENV{USERNAME}or$ENV{USER}. Encode the raw bytes of the user name each as two hex digits to obtainUSERHEX.PIDis the process ID. Forked children use the parent's PID.HASHis a crypto-hash of the entire par file or executable, calculated at creation time. This value can be overloaded withpp's--tempdirparameter.
By default, PAR strips POD sections from bundled modules. In case that causes trouble, you can turn this off by setting the environment variable PAR_VERBATIM to 1.
π¦ import options π¦
When you use PAR {...} or call PAR->import({...}), the following options are available.
PAR->import({ file => 'foo.par' });
# or
PAR->import({ repository => 'http://foo/bar/' });
fileβ the par filename. You must pass one option of either'file'or'repository'.repositoryβ a par repository (exclusive offile).fallbackβ search the system@INCbefore the par. Off by default for loading.parfiles viafile => .... On by default for PAR repositories. To prefer loading modules from a repository over the locally installed modules, you can load the repository like this:
use PAR { repository => 'http://foo/bar/', fallback => 0 };
runβ the name of a script to run in the par. Exits when done.no_shlib_unpackβ skip unpacking bundled dynamic libraries fromshlib/$archname. The client may have them installed, or you may wish to cache them yourself. In either case, they must end up in the standard install location (such as/usr/local/lib/) or in$ENV{PAR_TEMP}before yourequirethe module which needs them. If they are not accessible before yourequirethe dependent module, perl will die with a message such as"cannot open shared object file..."π
π₯ SEE ALSO π₯
PAR::Tutorial- The
PAR::Packerdistribution which contains the packaging utilities:par.pl,parl,pp. PAR::Distfor details on PAR distributions.PAR::Repository::Clientfor details on accessing PAR repositories.PAR::Repositoryfor details on how to set up such a repository.Archive::Zip,"require" in perlfuncex::lib::zip,Acme::use::strict::with::pride- Steffen Mueller has detailed slides on using PAR for application deployment at
<http://steffen-mueller.net/talks/appdeployment/>. - PAR supports the
preforkmodule. It declares various run-time dependencies so you can use thepreforkmodule to get streamlined processes in a forking environment.
π ACKNOWLEDGMENTS π
- Nicholas Clark for pointing out the mad source filter hook within the (also mad) coderef
@INChook, as well as (even madder) tricks one can play withPerlIOto avoid source filtering. - Ton Hospel for convincing me to ditch the
Filter::Simpleimplementation. - Uri Guttman for suggesting
read_fileandpar_handleinterfaces. - Antti Lankila for making me implement the self-contained executable options via
par.pl -O.
See the AUTHORS file in the distribution for a list of people who have sent helpful patches, ideas or comments. π«Ά
π AUTHORS π
Okay so who made this whole thing? Say hi to the icons π
- Audrey Tang β
cpan@audreyt.org - Steffen Mueller β
smueller@cpan.org
And bestie, you can literally just write to the mailing list at par@perl.org β or if you're feeling fancy, send an empty mail to par-subscribe@perl.org and boom, you're in the discussion π«Ά Archives of the mailing list are right here whenever you wanna lurk:
Bug reports? Please send those to https://github.com/rschupp/PAR/issues πβ¨ But if what you actually need is support, then ngl the preferred move is joining the par@perl.org mailing list instead. iykyk π
π COPYRIGHT π
Copyright 2002-2010 by Audrey Tang <cpan@audreyt.org>. Copyright 2005-2010 by Steffen Mueller <smueller@cpan.org>
This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. β¨
See LICENSE.
no cap, that's the legal bit and it matters β same terms as Perl itself, fr fr πΈ
And that's a wrap on the whole page, bestie π This was PAR(3) from perl v5.42.0, dated 2025-08-04. Go forth and pack your Perl like the main character you are ππ¦
π¦ where this page comes from
- fedora 43: perl-PAR 1.021-1.fc43 Β· GPL-1.0-or-later OR Artistic-1.0-Perl
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms