Item 43: Make sure Perl can find the modules you are using.


From Item 42 you know that Perl modules are contained in files ending with the extension .pm , and that the use directive incorporates modules into your programs. However, a question that has gone unanswered thus far is:

"How does use find my modules, anyway?"

The answer is that Perl searches the module include path , a list of directories stored in the global variable @INC . The default include path is built into the Perl executable when Perl is compiled. There are a number of ways to see exactly what the current include path is. One, of course, is to write a little script that prints it out. From the command line, this will do the trick:

 %  perl -e 'print "include is @INC\n" '  

A slightly easier-to-type alternative is to check Perl's configuration with the -V command line option:

 %  perl -V  Summary of my perl5 (5.0 patchlevel 4 subversion 1)  configuration:  Platform:      osname=solaris, osvers=2.5.1, archname=sun4-solaris . . .  blah blah blah  . . .      Characteristics of this binary (from libperl):    Built under solaris    Compiled at Jun 16 1997 15:37:41    @INC:      /usr/local/lib/perl5/sun4-solaris/5.00401      /usr/local/lib/perl5      /usr/local/lib/perl5/site_perl/sun4-solaris      /usr/local/lib/perl5/site_perl      . 

No matter how you look at it, the include path lists the directories in which the use directive will search for Perl modules, or, in the case of nested modules like File::Basename , the directories in which the various module trees like File are rooted.

Modifying the include path

If you have modules installed in places other than those listed in the built-in @INC , you will have to modify the include path to get Perl to use them. Under normal circumstances, this won't happen very often. When you build and install moduleseither by using the CPAN module or by just unpacking and making them manuallyPerl's MakeMaker module automatically generates a makefile that will put the module's .pm file in the correct location for your particular installation of Perl. If that's not where you want the module to go, you have to force MakeMaker to put it somewhere else (see Item 42).

But let's assume you have a module installed in a strange place, say, in the directory /share/perl . You might be tempted to just modify the include path in your program's source code:

 unshift @INC, "/share/perl"; 

Where MyModule.pm lives.

 use MyModule; 

WRONG! No effect.

Unfortunately, this simple approach will not work . The problem is that the use directive is a compile-time rather than a run-time feature. When use Module appears in your program, it actually means:

 BEGIN { require "Module.pm"; import Module; } 

The code inside the BEGIN block is executed at compile time rather than run time. This means that changes to @INC at run time have no effect on use directives. (For more information about BEGIN , see Item 59. For more about require , see Item 54.)

A rather blunt way around this is to put the change to @INC in a BEGIN block of its own:

 BEGIN {    unshift @INC, "/share/perl";  }  use MyModule; 

Where MyModule.pm lives.

It works now!

Now, the include path is set up at compile time, and use can find the module. Although this is a workable strategy, there is a better way to control the include path: the lib pragma module. The lib pragma was added fairly early in the development of Perl 5, and all recent versions support it. To prepend one or more directories to the include path, just supply them as arguments to use lib :

 use lib "/share/perl";  use lib qw(    /xtra/perl    /xtra/perl5  ); 

Add dir /share/perl.

Add more dirs.

 use MyModule; 

Ready to go now.

Aside from improved readability, use lib has one other advantage over explicit changes to the include path. The lib pragma also adds a corresponding architecture-specific autoload path, if such a directory exists. This can result in improved performance if you are using a module that is autoloaded. For example, if the machine architecture is "sun4-solaris" , then use lib "/share/perl" will add:

 /share/perl/sun4-solaris/auto 

in addition to /share/perl , if the autoload directory exists.

There are some other ways to control the include path in those cases in which use lib isn't appropriate. You can use the -I command line option:

 %  perl -I/share/perl myscript  

You can also use -I in the " pound bang" line:

 #! /usr/local/bin/perl -I/share/perl 

Finally, you can put one or more directory names , separated by colons, in the PERL5LIB environment variable.

Modifying the include path: special cases

As I mentioned earlier, the include path is built into Perl when it is compiled. Generally, it will derive from the installation prefix specified when the Configure script is run:

 Installation prefix to use? (~name ok) [/usr/local] 

Changing the installation prefix allows you to build and install private or alternative copies of Perl for testing or perhaps debugging purposes (see Item 38).

Ordinarily the built-in modules and library files go into the subdirectory lib/perl5 underneath the prefix directory, say, /usr/local/lib/perl5 . It's a good idea to leave them there, but if you want them to go somewhere else, you can also control that with Configure :

 Pathname where the private library files will reside? (~name ok) [/usr/local/lib/perl5] 

If you change the private library directory, the include path for this version of Perl will also be changed accordingly . Finally, if you are writing a Perl module, you may want to test scripts against it without actually installing the module. The blib (build library) pragma module is useful in these cases:

 #!/usr/local/bin/perl 
 
 use blib "/home/joseph/Magic"; 

Looks for blib in /home/joseph/Magic .

although it is more often used from the command line:

 %  perl -Mblib my_script  

Looks for blib in the current directory.



Effective Perl Programming. Writing Better Programs with Perl
Effective Perl Programming: Writing Better Programs with Perl
ISBN: 0201419750
EAN: 2147483647
Year: 1996
Pages: 116

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net