5.2 Modules and use
Modules are nothing but packages. In the example of packages we see in the previous section, we use three packages, but all three are defined within the same file. In Perl, a file can have many packages or a package can span over many files. The language puts no strictures on how packages should be organized. However, if we restrict one package to one file, what we get are called modules. In Perl, the name of the file (i.e., the name of the module) in which the package is stored must be the same as the name of the package, but with a .pm extension. pm stands for Perl
module. So, if the name of the package corresponding to a module is a_package, the name of the file where the package is stored must be called a_package.pm.
We now rework the example that we saw in the previous section and build modules out of the packages. We write three modules Sean, Tommy, and another one that has a slightly longer name Friends::Chad. We discuss the significance of the long name for the last module shortly. We also have the main program. So, there are a total of four files.
To create the first two modules, we create two files Sean.pm and Tommy.pm in the current directory. The files need not have execute permission. The file Sean.pm holds the definition of the Sean package. Its contents are what we have seen earlier, but repeated below.
Program 5.2
#!/usr/bin/perl #file Sean.pm package Sean; $firstname = "Sean"; $hometown = "Montreal"; $height = 67; $weight = 140; $age = 21; $year_met = 1995; 1;
This file declares that we are inside the Sean package, and assigns value to a few scalar variables. The definition of a package must return true. The use function returns the value of the last statement in the package in addition to making the package’s definition available where it is used. Usually, the last statement of a package is
1;
which is the quitessential true statement. The contents of the file Tommy.pm are also repeated below. They are quite similar to the contents of the Sean.pm file.
Program 5.3
#!/usr/bin/perl #file Tommy.pm package Tommy; $firstname = "Tommy"; $hometown = "Washington DC"; $height = 66; $weight = 140; $age = 18; $year_met = 1997; 1;
To store the third module, we create a directory called Friends in the current directory. In this directory, we create a file called Chad.pm. The contents of the file Friends/Chad.pm are given below. This file also does not have to be executable.
Program 5.4
#!/usr/bin/perl #file Friends/Chad.pm package Friends::Chad; $firstname = "Chad"; $hometown = "San Francisco"; $height = 73; $weight = 180; $age = 23; $year_met = 1995; 1;
Note that the package has been declared with the name Friends::Chad and not simply Chad.
Now, let us look at the main program. In the main program, we want to have access to the contents of all the three modules and print the values the variables have been assigned in the three modules. Here is the main program.
Program 5.5
#!/usr/bin/perl
#file simple2package.pl
use Sean;
use Tommy;
use Friends::Chad;
printf "%s\t%s\t%s\t%s\t%s\t%s\n", $Friends::Chad::firstname,
$Friends::Chad::hometown, $Friends::Chad::height, $Friends::Chad::weight,
$Friends::Chad::age, $Friends::Chad::year_met;
printf "%s\t%s\t%s\t%s\t%s\t%s\n", $Tommy::firstname, $Tommy::hometown,
$Tommy::height, $Tommy::weight, $Tommy::age, $Tommy::year_met;
printf "%s\t%s\t%s\t%s\t%s\t%s\n", $Sean::firstname, $Sean::hometown,
$Sean::height, $Sean::weight, $Sean::age, $Sean::year_met;
The first two modules that are in the same directory as the main program are accessed by writing the statements
use Sean;
use Tommy;
However, to access the contents of the module named Friends::Chad that is stored as Chad.pm in the subdirectory Friends, we need to write
use Friends::Chad;
Additional levels of subdirectories can be used if appropriate for the task at hand. To get the value of a variable such as $hometown in the Friends::Chad package, we need to write $Friends::Chad::hometown. Otherwise, nothing is much different from the program given in the previous subsection on packages. The output of executing the main program is the same as what we see in the previous section. If we use the use statement, the names can be used without qualifiers.
However, in this case, without the package name qualifier, the names are ambiguous.
A package, in its definition, can have a list of exported variables. A package can export variables that are globally available. A variable that is available globally inside a package may be
1. global only within the package, or
2. global within the block in which the package lies.
As an example of the second type of global variable occurs when a variable is global in a file that contains several packages. There are several ways of creating global variables of various kinds.
1. A variable that is undeclared and just used in an expression or a statement is a global variable. An undeclared global variable inside a package need not be explicitly exported.
2. A variable declared with my is not considered global, and thus, cannot be exported and made available outside a package.
3. A variable declared with our is considered global within a block (which may contain one or more packages), and thus, can be exported and made available outside the home package.
4. A variable declared with the pragma use vars is considered global inside a package, and thus, can be exported and made available outside the home package.
The use function imports the named package’s list of exported variables. Exported variables are ones that have been explicitly exported by the module within its definition. An exported identifier can be used without using the package qualifier although it is a good habit to use the package qualifier even when not needed so that the source package of a variable name, a filehandle, or a subroutine is always clear. This is especially so if there are many modules being used. In the current set of modules, we have not explicitly exported any identifiers from the Sean,
Tommy and Friends::Chad modules. However, non-exported global variables such as the ones we see in these three modules are available anywhere else if we use fully qualified names. Thus, it is not possible to make variables in the three modules discussed here, invisible or private to a module even if we want to because of the way these modules are written at this time. Of course, an identifier or a name in a module can be made selectively available outside. We see how to do such selective exporting of variable names later.
When we write one or more modules, it is possible that we organize them tidily by placing them in a clearly named directory. For example, if in this case, we create a directory called friendlib with the full path /home/kalita/perl/packages/friendlib, we can make the modules available in Perl program by useing the pragma called lib before we use the modules. So, if Sean.pm and Tommy.pm are situated in
/home/kalita/perl/packages/friendlib and Chad.pm is situated in the directory
/home/kalita/perl/packages/friendlib/Friends, the following sequence works.
use lib '/home/kalita/perl/packages/friendlib';
use Sean;
use Tommy;
use Friends::Chad;
A module installed by a system’s administrator resides in one or more pre-designated directories for Perl libraries. For example, on a Linux machine, it usually is one or more sub-directories in the directory /usr/lib/perl5 for Perl 5. Perl has a large number of libraries that come with the core distribution. They are normally placed below /urs/lib/perl5 in one sub-directory whose name is the Perl version number, say 5.8.0 or 5.005. Usually, all modules downloaded later are placed in a directory called site_perl under /usr/lib/perl5. If a user-written set of Perl modules are placed in a new sub-directory in /usr/lib/perl5, it is not necessary to specify the location of the modules using use lib as long as the module name clearly specifies the directory and file structure below the /usr/lib/perl5 directory. Of course, the names of all the directories can vary from
system to system. The module files and all directories above them must be accessible to everyone. This means, in Unix, the files must be readable by everyone. All directories must be readable and executable by everyone in Unix. In a non-Unix environment, accessibility permissions are usually not an issue.
Finally, we also see that a module is reusable code. It can be written by one person, then given to another who can use it as long as it is placed where Perl can find it.