2.5 require and @INC

So far, the examples have glossed over the directory structure of where the main code and the included files (either with do or require) are located. That's because it "just works" for the simplest case, in which you have a program and its libraries in the same directory, and you run the program from that directory.

Things get a bit more complicated when the libraries aren't located in the current directory. In fact, Perl searches for libraries along a library search path (similar to what the shell does with the PATH environment variable). The current directory (represented in Unix by a single dot) is an element of the search path, so as long as your libraries are in your current working directory, everything is fine.

The search path is given in the special @INC array. By default, the array contains the current directory and a half-dozen directories built in to the perl binary during the compilation of perl itself. You can see what these directories are by typing perl -V at the command line and noting the last dozen lines of the output. Also at the command line, you can execute the following to get just the @INC directories:[7]

[7] On a Windows machine, use double quotes instead of single quotes on the command line.

perl -le 'print for @INC'

Except for . in that list, you probably won't be able to write to any of the other directories, unless you're the person responsible for maintaining Perl on your machine, in which case you should be able to write to all of them. The remaining directories are where Perl searches for system-wide libraries and modules, as you'll see later.

2.5.1 Extending @INC

Although you may not be able to alter the content of the directories named by @INC, you can alter @INC itself before the require, to bring in libraries from one or more directories of your choosing. The @INC array is an ordinary array, so have the Skipper add a directory below his home directory to the mix:

unshift @INC, "/home/skipper/perl-lib";

Now, in addition to searching the standard directories and the current directory, Perl searches the Skipper's personal Perl library. In fact, Perl searches in that directory first, since it is the first one in @INC. By using unshift rather than push, any conflict in names between the Skipper's private files and the system-installed files are resolved with the Skipper's file taking precedence.

2.5.2 Extending @INC with PERL5LIB

The Skipper must edit each program that uses the private libraries to include this line. If that seems like too much editing, the Skipper can instead set the PERL5LIB environment variable to the directory name. For example, in the C shell, it'd be:

setenv PERL5LIB /home/skipper/perl-lib

In Bourne-style shells, it'd be something like:

PERL5LIB=/home/skipper/perl-lib; export PERL5LIB

The advantage of using PERL5LIB is that the Skipper can set it once and forget it. The disadvantage comes when someone else (like Gilligan) comes along to execute the program. Unless Gilligan has also added the same PERL5LIB environment variable, the program will fail! Thus, while PERL5LIB is interesting for personal use, do not rely on it for programs you intend to share with others. (And don't make your entire team of programmers add a common PERL5LIB variable. That's just wrong.)

The PERL5LIB variable can include multiple directories, separated by colons. Any specified directory is inserted at the beginning of @INC.

While a system administrator might add a setting of PERL5LIB to a system-wide startup script, this process is generally frowned upon. The purpose of PERL5LIB is to enable nonadministrators to extend Perl to recognize additional directories. If a system administrator wants additional directories, he merely needs to recompile and reinstall Perl, answering the appropriate questions during the configuration phase.

2.5.3 Extending @INC with -I

If Gilligan recognizes that one of the Skipper's programs is missing the proper directive, Gilligan can either add the proper PERL5LIB variable or invoke perl directly with one or more -I options. For example, to invoke the Skipper's get_us_home program, the command line might be something like:

perl -I/home/skipper/perl-lib /home/skipper/bin/get_us_home

Obviously, it's easier for Gilligan if the program itself defines the extra libraries. But sometimes just adding a -I fixes things right up.[8]

[8] Extending @INC with either PERL5LIB or -I also automatically adds the version- and architecture-specific subdirectories of the specified directories. Adding these directories automatically simplifies the task of installing Perl modules that include architecture- or version-sensitive components, such as compiled C code.

This works even if Gilligan can't edit the Skipper's program. He still has to be able to read it, of course, but Gilligan can use this technique to try a new version of his library with the Skipper's program, for example.