Hack #29. Manage Module Paths

Keep your code where it makes sense to you, not just to Perl.

Perl's a flexible language and it tries to make few assumptions about your environment. Perhaps you're a system administrator with root access and a compiler and can install modules anywhere you want. Perhaps you only have shell access on a shared box and have to submit a change request to have something installed. Perhaps you want to test one set of modules against one program but not another.

Whatever the case, Perl gives you options to manage where it looks for modules. Suppose you have a program in your ~/work directory that uses a module named Site::User. By default, Perl will search all of the directories in the special @INC variable for a file named Site/User.pm. That may not always include the directory you want (especially if, in this case, you want ~/work/lib). What can you do?

Within Your Program

The simplest and most self-contained way to change Perl's search path is within your program by using the lib pragma. This happens at compile-time [Hack #70], as soon as perl encounters the statement, so put it before any use line for the module you want to load. For example:

use lib 'lib';
use Site::User;

adds the lib/ directory—relative to the current directory—to the front of Perl's search path list. Similarly:

no lib 'badlib';
use Site::User;

removes the badlib/ directory from Perl's list of search paths. If you have two versions of Site::User installed and want to make sure that Perl doesn't pick up the wrong version from the wrong directory, exclude it.

From the Command Line

Sometimes you don't have the option or the desire to modify a program, though, especially when you're merely testing it. In that case, use the lib pragma from the command line when invoking the program by using perl's -M switch:

$ perl -Mlib=lib show_users.pl
            

This is equivalent to use lib 'lib'. To exclude a path, prepend a hyphen to lib:

$ perl -M-lib=badlib show_users.pl
            

Tip

The -I flag also lets you include paths, but it does not let you exclude them.

With an Environment Variable

Of course, modifying every program or remembering to add a command-line switch to every invocation is a tremendous hassle. Fortunately, there's a third option: set the PERL5LIB environment variable to a colon-separated list of directories to add to the search path. Depending on your shell, this may be:

$ export PERL5LIB=/home/user/work/lib:/home/user/work_test/lib:$PERL5LIB

% setenv PERL5LIB /home/user/work/lib:/home/user/work_test/lib:$PERL5LIB
            

There's no good and easy way to exclude a directory for the search path here; put the correct directory at the front of the path.

If you put the appropriate invocation in the appropriate startup file (such as /etc/profile or the equivalent), users do not even have to know that this path is there. Of course, if they run programs from cron or another environment without these variables, some paths may not be present.

An easier option may be to write a simple shell script that sets the environment properly and then launches the actual perl binary, passing along the command-line options appropriately.

When Recompiling Perl

Your final recourse is to set the appropriate paths when compiling Perl [Hack #67]. This isn't as bad as it sounds, but it does take a little bit more dedication. Once you have downloaded and unpacked Perl, run the Configure script. Answer all of the questions appropriately until it asks:

Enter a colon-separated set of extra paths to include in perl's @INC
search path, or enter 'none' for no extra paths.

Colon-separated list of additional directories for perl to search? [none]

Type there the list of directories to add to Perl's built-in @INC. Note that perl will search this directory after it searches its core directories, so if you want to load something in place of a core module, you must manipulate the path with one of the other techniques.

Get Perl Hacks now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.