Installing, and finding what you installed#
The command#
Everything after --cpan goes to the CPAN client, so any option of the cpan command you already know still works: -T to skip the tests, -f to force an install.
pperl --cpan Text::CSV
pperl --cpan Plack Starman
pperl --cpan -T Try::Tiny
Besides module names, --cpan takes a git repository: a URL that starts with git: or ends in .git. It is cloned and installed from the clone. Append @ and a branch, tag or commit to install that revision.
pperl --cpan https://github.com/example/Some-Dist.git
pperl --cpan https://github.com/example/Some-Dist.git@v1.2
With nothing to install, it says so rather than guessing:
pperl --cpan
# pperl: --cpan: nothing to install: pperl --cpan Module::Name [...]
Where it goes#
Modules land in a pperl-owned tree, never in a perl5 one. The base is $PPERL_HOME, or ~/.pperl if that is unset:
~/.pperl/
├── lib/perl5/ <- the modules
└── cpan/ <- the installer's downloads and builds
--cpan --system writes to /usr/local/share/pperl instead, for a machine-wide install. That path needs the privileges you would expect.
Keeping the tree separate is deliberate. A machine commonly has both pperl and a real perl5, and a module built for one has no business being found by the other.
Making pperl see it#
An install does not put itself on the search path. The last line of a successful run tells you what to set:
pperl --cpan Text::CSV
# pperl: installed into /home/you/.pperl/lib/perl5
# pperl: add it to your path with PPERL5LIB=/home/you/.pperl/lib/perl5
PPERL5LIB is the pperl-private twin of PERL5LIB: same syntax, colon-separated, but read only by pperl. Put it in your shell profile and be done:
export PPERL5LIB="$HOME/.pperl/lib/perl5"
It is honoured ahead of PERL5LIB and ahead of every system tree, so a module you installed for pperl outranks a same-named copy belonging to the host perl. You can see the effect directly:
pperl -e 'print "$_\n" for @INC'
# /usr/share/perl5/site_perl
# /usr/lib/perl5/5.42/site_perl
# ...
PPERL5LIB=/home/you/.pperl/lib/perl5 pperl -e 'print "$_\n" for @INC'
# /home/you/.pperl/lib/perl5 <- first
# /usr/share/perl5/site_perl
# ...
Why a separate variable rather than reusing PERL5LIB: on a machine running both interpreters, PERL5LIB is usually already pointing at the host perl’s trees. Overloading it would force you to choose between the two. Both are read, PPERL5LIB first.
Why pperl reads the system trees at all#
pperl searches the host perl’s directories because a pure-Perl module found there runs perfectly well under pperl. That is free inventory and there is no reason to refuse it.
What pperl does not search is any architecture directory. Those hold compiled extensions, which pperl cannot load. This matters more than it sounds, and the no-XS rule explains where it bites.
Installing without a network#
A distribution archive or an unpacked directory on disk installs without a download of its own. Name a directory with a leading ./ or /, so that it cannot be taken for a module name:
pperl --cpan ./Some-Dist-1.23.tar.gz
pperl --cpan ~/src/Some-Dist
The client still fetches the CPAN index on its first run, and any dependency that is not installed yet.
Tests run non-interactively: PERL_MM_USE_DEFAULT and NONINTERACTIVE_TESTING are both set, so a distribution that would otherwise stop to ask a question takes its own default instead of hanging.