6.2 Modules
Modules make it easy to reuse Perl code in multiple programs. Writing a Perl module involves defining a set of variables and subroutines within a package, and then making those definitions available for public consumption. Just as you can avoid repeating code within a program by using subroutines, you can avoid repeating code within a set of programs by writing a module. In this section, we will see just how easy it is to create and use Perl modules.
6.2.1 Creating a module
To write a module, create a file with a .pm suffex. The file should define global variables and subroutines, all within a package with a name that is the same as the filename. If the file is named Foo.pm, then it should define variables and subroutines in the package Foo. (User-defined module and package names traditionally begin with capital letters.) If the package name contains ::, such as Food::Cooking, then the file should be named Cooking.pm, placed within a directory named Food. Perl translates the hierarchy separator :: into a directory separator, regardless of what platform you're running. Food::Cooking would thus be in Food/ Cooking.pm on a Unix system, and Food\Cooking.pm on a Windows system. Within a Perl program, these platform-specific differences are normally invisible.
A module will normally begin with a package statement, naming the package in which the module's variables and subroutines will be placed. So in Food::Cooking, the first line would be:
package Food::Cooking;
The last line of a module must evaluate to true. This is traditionally done by putting the number 1 on the final line:
1;
The following is a perfectly legal definition of the Mathtest module, which defines two variables and a subroutine:
use strict; package Mathtest; our ($pi, $e); $pi = 3.14159; # Define $Mathtest::pi $e = 2.7182818; # Define $Mathtest::e sub circle_area # Declare a subroutine { # Get the argument to our subroutine my $radius = shift; # Return the calculated area return ($pi * $radius * $radius); } 1; # Loaded successfully
6.2.2 Using our module
Once Mathtest has been created, a program can use it with the compile-time use statement:
use Mathtest;
A program can also use the -M command-line argument:
perl -MMathtest -e 'print "$Mathtest::pi\n";'
This could be rewritten as:
perl -e 'use Mathtest; print "$Mathtest::pi\n";'
6.2.3 Details of module loading
The array @INC lists the directories in which Perl should look for modules. When it encounters a use statement, Perl looks through the directories in @INC sequentially, stopping when it finds a match.
The following one-liner displays the contents of @INC:
perl -e 'print join "\n", @INC, "\n";'
On my computer, this program displayed the following:
usr/local/lib/perl5/5.6.1/i686-linux usr/local/lib/perl5/5.6.1 usr/local/lib/perl5/site_perl/5.6.1/i686-linux usr/local/lib/perl5/site_perl/5.6.1 usr/local/lib/perl5/site_perl/5.6.0/i686-linux usr/local/lib/perl5/site_perl/5.6.0 usr/local/lib/perl5/site_perl
If Mathtest.pm is in any of these directories, then use Mathtest within our program will work. If Perl cannot find Mathtest.pm in any of these directories, the program exits with a fatal compilation error. . represents the current directory, meaning that Perl will normally look for modules in the same directory as an executing program. Activating taint mode (see Section 13.3) removes . from @INC, as a safety precaution.
A program can add a directory to @INC with use lib:
use lib "/usr/random/directory";
use lib adds directories to the front of @INC, giving them priority over the default directories. Command-line programs can have the same effect with -I:
perl -I/usr/local/perl/modules -I/home/joeuser/modules -MJoe -w
When Perl finds and loads a module with use, it adds a keyvalue pair to %INC. Each key in %INC is a module name, and its corresponding value is the file from which it was loaded. This ensures that each module is loaded only once, even if it appears in two use statements.
6.2.4 Using modules
Once a module is loaded, its variables and subroutines are available to a program. For example:
use Mathtest; my $log_base = $Mathtest::e; print "Log base: $log_base\n"; # Prints 2.7182818 my $radius = 10; my $area = Mathtest::circle_area($radius); print "Area = $area\n"; # Prints 314.159
Globals declared in a module are no different from any other global variables. We can thus modify global variables defined in a module, as the following code demonstrates:
use Mathtest; # Import the module $Mathtest::pi = 4; # Redefine pi! my $radius = 10; my $area = Mathtest::circle_area($radius); print "$area\n"; # Prints 400
It is generally a bad idea to redefine variables defined by a module unless the module's documentation encourages such behavior explicitly.
6.2.5 Lexicals in modules
Lexical variables, as we have already seen, look similar to global variables but act quite differently. Every global is associated with a package and lasts until the program exits. By contrast, lexicals do not have any associated package and disappear when their enclosing block goes out of scope.
Because they lack a package, lexical variables defined at a module's top-level scope are invisible to programs outside of the module. This can sometimes be useful, but it usually leads to confusionparticularly for the programmer who cannot figure out why he or she cannot access a module's variables!
Understanding the difference between globals and lexicals is a key part of programming in Perl, and this is especially true when working with modules. Although it is normally a good idea to use lexicals wherever possible, this does not include module variables that must be visible to the outside world.