How do YOU manage Perl modules when using a package manager? How do YOU manage Perl modules when using a package manager? linux linux

How do YOU manage Perl modules when using a package manager?


For development, I install my own Perl and leave the system Perl alone. If I want to upgrade the system Perl, I use the system package manager. For my development Perl, I use the cpan tool.

Since I keep those separate, I should never mess up the Perl that the system needs for its maintenance tasks and so on, but I don't have to rely on the system's decisions for development.

It's very easy to install separate Perls. When you run Configure from the source distribution, it will ask you where you want to install everything. Give it any path that you like. I have many Perls installed in /usr/local/perls, for instance, and everything for each installation lives separately. I then make symlinks in /usr/local/bin for them (e.g. perl5.8.9, perl.5.10.0, perl5.10.0-threaded). When I want a particular version, I just use the one I want:

$ perl5.10.0 program.pl

The particular binary ensures that the program picks up the right module search path and so on (it's the same stuff in the Config.pm module for that binary).

Here's a script I use to create the symlinks. It looks in the bin directory, figures out the Perl version, and makes links like cpan5.10.1 and so on. Each program already knows the right perl to call:

#!perluse 5.010;use strict;use warnings;use File::Basename;use File::Spec::Functions;my $perls_directory = catfile(    $ARGV[0] // '/usr/local/perls',     'perl*');die "$perls_directory does not exist!\n"     unless -d dirname $perls_directory;my $links_directory = $ARGV[1] // catfile( $ENV{HOME}, 'bin' ); #/die "$links_directory does not exist!\n" unless -d $links_directory;foreach my $directory ( glob( $perls_directory ) ){    say "Processing $directory...";    unless( -e catfile( $directory, 'bin' ) )    {        say "\tNo bin/ directory. Skipping!";        next;    }    my @perls = glob( catfile( $directory, qw( bin perl5* ) ) );        my( $perl_version ) = $perls[0] =~ m/(5\.\d+\.\d+)\z/;    say "\tperl version is $perl_version";    foreach my $bin ( glob( catfile( $directory, 'bin', '*' ) ) )    {        say "\tFound $bin";        my $basename = basename( $bin );        my $link_basename = do {            if( $basename =~ m/5\.\d+\.\d+\z/) { $basename }            else                               { "$basename$perl_version" }        };        my $link = catfile( $links_directory, $link_basename );        next if -e $link;        say "\t\tlinking $bin => $link";        symlink $bin => $link or            warn "\t\tCould not create symlink [$!]: $bin => $link!";    }}

Everything gets install in the right place for that particular Perl.

I've also been thinking that I should put those Perl directories under some sort of source control. If I add a module I don't like, I just back out to an earlier revision. I'm only starting to do that though and haven't played with it much.

I've written more about this sort of thing in the Effective Perler blog:


We install everything via the CPAN shell. This does ignore what package managers have to offer, but it avoids the headaches you mention when trying to work with them (firing for dependencies, using correct versions).

In addition, it means that our packages can be built programatically (or manually via the shell) on any platform where CPAN runs. Having a dependency on a package manager would affect your ability to distribute your software to platforms that don't use/support that package manager.


Since this question was originally asked, perlbrew has been released. It makes installing custom, self-contained perl installs trivial. And switching between those versions is just as easy:

perlbrew switch $version