"Vendor" code, "Your" Code: Managing Different Package-Environments with PERL5LIB

When you start using Perl for a serious project, it doesn't take long before you start creating packages of your own. And you start grabbing packages, for your particular project, from places like CPAN. In this way, you start building-up a particular environment in which your application ... this one of your applications ... will run. Must run.

Problems can arise, though, from either of two different sources:

So... what you need to be able to accomplish here is to control which packages, and which versions of those packages, that a particular application will be able to “see.” You do that by controlling exactly where Perl will search to find the libraries that you use or require.

Here's where the PERL5LIB environment-variable comes in very handy. (Your operating-system supports them somehow, but different systems do so in slightly different ways.) This is a list of directory-locations, separated by “:” colons.

Nit-pickin' point:   It might be something other than PERL5LIB; see perldoc perlrun.

On your system, enter the command perl -V, with an upper-case "V". Notice the list that's labeled @INC, which of course stands for include. That's the list of libraries that Perl will search through when you say you want to use or require a package. The list will be searched in the order specified.

The tail of the @INC list is established when the Perl executable is built: you can't change that without recompiling Perl, and that can have far-reaching implications (such as, say, if your distro does all of its package-maintenance using Perl programs). But the head of that list, which after all is searched first, is under your control. It's controlled by PERL5LIB (among other things).

You can see this for yourself:   change the list, and perl -V will immediately reflect the change.

You can set PERL5LIB for your login-session by changing files like .bashrc on Unix/Linux systems. But you can also specify it the command-file that actually launches a particular application. Web-sites often use the Apache directive SetEnv to establish site-specific settings.

"There's more than one way to do it"™ and in this case that's really the essential point: you can have more than one, different and distinct, “way to do it.” This is great for keeping separate projects at arm's length from one another. And since your PERL5LIB setting is different from the system's, you won't interfere with what your vendor is doing nor with whatever he expects.

Here, for example, is “another way to do it”: the use lib directive. This is another way to specify the effective @INC path. It's often used in apps, such as CGI applications, where “the program file that you execute” is actually little more than a routine which does use lib, then instantiates a new Perl object, and then invokes that object's (say...) run method to do the actual work. “use lib,” like PERL5LIB, is just another way to influence what winds up in @INC for a particular application-instance when it runs.

Another nit:  It doesn't really matter where in the program-file the use lib directive is, because this directive is found and evaluated before anything else... particularly, before any use modulename and of course before any require.

When you are installing CPAN modules, you need to make sure that CPAN knows where to put things. That is an o conf setting such as PREFIX. These settings, and related files, are kept in the hidden .cpan directory of your login-account. (There is no "system global" file that I know of; when root makes system wide changes, root's settings are, as far as I know, only in root's home-directory.)

(As an aside, I had tremendous grief with this after “adopting” a new machine. Unbeknownst to me, the CPAN settings for root were putting modules into a target-location that wasn't on the @INC list. So, I was trying to make “global” system changes, and Perl would install them but having installed them would not see them. CPAN never offered a single clue or warning!)

For this reason, I keep separate login-accounts for each one of my web-client projects. And each one points to a set of library-directories where that project's libraries and modules and CPAN-modules “reside.”

Note: If your distro doesn't use CPAN to maintain its Perl-modules, you probably don't want to start using CPAN, i.e. as root, to make “system-wide” changes that could possibly conflict with what they are doing. When in Rome, pay very careful attention to what the Romans do.

Replies are listed 'Best First'.
Re: RFC (tutorial): "Vendor code, Your code", PERL5LIB
by Fletch (Bishop) on Nov 21, 2007 at 22:53 UTC

    You might also mention that many people prefer to have a separate installation of perl from the one installed with the OS in /usr/bin/perl (or what not) in order to decouple OS upgrades and what modules or versions that requires from what versions your application runs against. See for example Management of perl modules in enterprise? (that's the first hit I'm getting for obvious search terms, but it's come up before).

      Yes, I think this is a really important issue, but possibly this doesn't go far enough. It's not hard at all to run into situations where you need to run many versions of perl on the same box, each of which may need it's own set of modules. For example, consider a web developer's linux workstation, where you might want:

      1. the distribution's version
      2. the version on the web servers
      3. a candidate for the next web server upgrade
      4. the latest released version
      5. blead perl

      A tutorial describing a few (preferably very few) ways of dealing with this administration problem would be very useful.

        The easiest is to recompile perl to different locations. For example:
        # extract perl distribution and then: sh configure.gnu --prefix=/usr/perl5.10.0 make all test && sudo make install