Chapter 12. Modularize It, Package It, and Send It to the Library!

12.1. Packages and Modules
12.1.1. Before Getting Started
In the following sections, we discuss packages and modules found in the standard Perl library and how to use them. Many of today's modules use an object-oriented approach to programming, discussed in Chapter 14, which will include terms such as classes, objects, and methods. This chapter will focus on function-oriented modules and libraries and how to use and create them. We will also show you how to get modules from CPAN, the Comprehensive Perl Archive Network, but will go into more detail on installing and using CPAN modules in Chapters 14, 15, and 18.
12.1.2. An Analogy
Two boys each have a box of Legos building blocks. One set of Legos blocks will build a toy boat, the other a toy plane. The boys open their boxes and throw the contents on the floor, mixing them together. The Legos blocks are different shapes and colors. There are yellow square pieces, red triangular pieces, and blue rectangular pieces from both boxes, but now they are mixed up so it is difficult to tell which Legos blocks should be used to build the toy boat or the toy plane. If the pieces had been kept in their separate boxes, this confusion never would have happened.
In Perl, the separate boxes are called packages, and the Legos blocks are called symbols; i.e., names for variables and constants. Keeping symbols in their own private packages makes it possible to include library modules and routines in your program without causing a conflict between what you named your variables and what they are named in the module or library file you have included.
12.1.3. Definition
The bundling of data and functions into a separate namespace is termed encapsulation (to C++ programmers, this is called a class, and to object-oriented Perl programmers it can also be called a class). The separate namespace is termed a package. A separate namespace means that Perl has a separate symbol table for all the variables in a named package. By default, the current package is called package main. All the example scripts up to this point are in package main. By default, all variables are global within the package. The package mechanism allows you to switch namespaces, so that variables in the package are private, even if they have the same name somewhere outside of the package. (See Figure 12.1.)

The scope of the package is from the declaration of the package to the end of the file, end of the innermost enclosing block, or until another package is declared. Normally, a package is of file scope. To reference a package variable in another package, the package name is prefixed by the funny character representing the data type of the variable, followed by two colons and the variable name. In ancient Perl 4, an apostrophe is used instead of the colon. (The double colons are reminiscent of the C++ scope resolution operator.) When referring to the main package, the name of the package can be eliminated.
Perl 5 extends the notion of packages to that of modules. A module is a package that is usually defined in a library and is reusable. Modules are more complex than simple packages. They have the capability to export symbols to other packages and to work with classes and methods. A module is a package stored in a file, where the basename of the file is given the package name appended with a .pm extension. The use function takes the module name as its argument and loads the module into your script.
$package'variable
$package::variable
$main::variable
$::variable
12.1.4. The Symbol Table
To compile a program, the compiler must keep track of all the names for variables, filehandles, directory handles, formats, and subroutines that are used. Perl stores the names of these symbols as keys in a hash table for each package. The name of the hash is the same name as the package. The values associated with the hash keys are the corresponding typeglob values, know as aliases. The typeglob "globs" onto all types that could be represented by the name of the symbol. (See aliases and typeglobs, Chapter 11.) Perl actually creates separate internal pointers for each of the values represented by the same name. (See Figure 12.2.)

Each package has its own symbol table. Any time you use the package declaration, you switch to the symbol table for that package.
A variable assigned using the local function can be accessed in another package by using a :: to qualify it by package name. It is still within scope and accessible from the main symbol table.
The variables assigned using the my function are not accessible outside their own packages. They are not stored in a package symbol table but are stored in a private scratch pad created for each subroutine called. So when we use "my" variables, they cannot be accessed via the package symbol table, because they aren't there!
In the following example, you will notice that the main package stores not only symbols that are provided by the program but also other symbols, such as STDIN, STDOUT, STDERR, ARGV, ARGVOUT, ENV, and SIG. These symbols and special variables such as $_ and $! are forced into package main. Other packages refer to these symbols unless qualified. Example 12.1 shows the contents of the symbol table for the main package.
Example 12.1.
Code View: (The Script)
#!/bin/perl
# Package main
1 use strict "vars";
2 use warnings;
3 our ( @friends, @dogs, $key, $value ); # Declaring variables
4 my($name,$pal,$money);
5 $name="Susanne";
6 @friends=qw(Joe Jeff Jan );
7 @dogs = qw(Guyson Lara Junior);
8 local $main::dude="Ernie"; # Keep strict happy
9 my $pal = "Linda"; # Not in the symbol table
10 my $money = 1000;
11 while(($key, $value) = each (%main::)){
# Look at main's symbol table
print "$key:\t$value\n";
}
(Output)
Name "main::dude" used only once: possible typo at packages line 10.
STDOUT: *main::STDOUT
@: *main::@
ARGV: *main::ARGV
STDIN: *main::STDIN
: *main::
dude: *main::dude
attributes::: *main::attributes::
DB::: *main::DB::
key: *main::key
_<..\xsutils.c: *main::_<..\xsutils.c
_<perllib.c: *main::_<perllib.c
UNIVERSAL::: *main::UNIVERSAL::
?: *main::?
value: *main::value
DynaLoader::: *main::DynaLoader::
?: *main::?
?ARNING_BITS: *main::?ARNING_BITS
SIG: *main::SIG
Exporter::: *main::Exporter::
Win32::: *main::Win32::
warnings::: *main::warnings::
BEGIN: *main::BEGIN
stderr: *main::stderr
INC: *main::INC
_: *main::_
": *main::"
DATA: *main::DATA
_<.\win32.c: *main::_<.\win32.c
$: *main::$
stdout: *main::stdout
IO::: *main::IO::
ENV: *main::ENV
dogs: *main::dogs
strict::: *main::strict::
stdin: *main::stdin
Carp::: *main::Carp::
CORE::: *main::CORE::
/: *main::/
0: *main::0
friends: *main::friends
_<..\universal.c: *main::_<..\universal.c
STDERR: *main::STDERR
main::: *main::main::
The strict pragma is turned on, barring any global variables. The warnings pragma issues warnings if there are barewords, uninitialized variables, etc. Lexically global our variables are declared. They will not be picked up as global variables by the strict pragma. Lexically scoped my variables are declared. The my variable, $name, is assigned Susanne. The array @friends is assigned a list of names. The array @dogs is assigned a list. In order to keep the strict pragma from complaining, the local variable $dude must be fully qualified with the package name. The lexically scoped my variable is assigned a value. This variable will not show up on the symbol table. It is stored in a special scratch pad within the block. This my variable will also be absent from the symbol table. The keys and values from the main symbol table are printed. The key is the name of the identifier, and the value is the corresponding typeglob value.
|
Example 12.2.
(The Script)
# Default package is main
1 @town = qw(Boston Chico Tampa);
2 $friend="Mary";
3 print "In main: \$friend is $friend\n";
4 package boy; # Package declaration
5 $name="Steve";
6 print "In boy \$name is $name.\n";
7 $main::friend="Patricia";
8 print "In boy \@town is @::town\n";
9 package main; # Package declaration
10 print "In main: \$name is $name\n";
11 print "In main: \$name is $boy::name\n";
12 print "In main: \$friend is $friend.\n";
(Output)
3 In main: $friend is Mary
6 In boy $name is Steve.
8 In boy @town is Boston Chico Tampa
10 In main: $name is
11 In main: $name is Steve
12 In main: $friend is Patricia
The default package is called main. In the main package an array, @town, is assigned values. @town is in main's symbol table. In package main, the scalar $friend is assigned Mary. $friend is in main's symbol table. The value of $friend is printed. The package boy is declared. We now switch from the main package to the boy package. This package has its own symbol table. From this point on until the program ends or another package is declared, the boy package is in scope. Variables created in this package are global within this package but not part of the main package. The scalar $name is assigned Steve. The value in $name is printed. To access the variable $friend in package main, first the dollar sign is prepended to the package name to indicate that the type of the variable is a scalar, followed by the name of the package, main, two colons, and the variable name, friend. This allows you to switch namespaces from within this package. Patricia is assigned to main's variable $friend. Since main is the default package, it is not necessary to use its name when switching namespaces. @::town tells Perl to switch namespaces back to the array @town in the main package. Package main is declared. We will now switch back into the main package. In the main package, $name is not defined. The value of the variable $name from the boy package is printed. The $friend scalar was changed in package boy because it was fully qualified with main's package main, meaning that the program was temporarily switched to package main when this variable was assigned. Its value is printed.
|
Example 12.3.
Code View: (The Script)
# Package declarations
1 $name="Suzanne"; # These variables are in package main
2 $num=100;
3 package friend; # Package declaration
4 sub welcome {
5 print "Who is your pal? ";
6 chomp($name=<STDIN>);
7 print "Welcome $name!\n";
8 print "\$num is $num.\n"; # Unknown to this package
9 print "Where is $main::name?\n\n";
}
10 package main; # Package declaration; back in main
11 &friend::welcome; # Call subroutine
12 print "Back in main package \$name is $name\n";
13 print "Switch to friend package, Bye ",$friend::name,"\n";
14 print "Bye $name\n\n";
15 package birthday; # Package declaration
16 $name="Beatrice";
17 print "Happy Birthday, $name.\n";
18 print "No, $::name and $friend::name, it is not your birthday!\n";
(Output)
5 Who is your pal? Tommy
7 Welcome Tommy!
8 $num is .
9 Where is Suzanne?
12 Back in main package $name is Suzanne
13 Switch to friend package, Bye Tommy
14 Bye Suzanne
17 Happy Birthday, Beatrice!!
18 No, Suzanne and Tommy, it is not your birthday!
Scalar $name is assigned Suzanne for the default package, main. Scalar $num is assigned 100. Package friend is declared. It is in scope until line 10. The subroutine welcome is defined within the friend package. The user is asked for input. $name is assigned a value. The package is friend. The value of $name is printed. The scalar $num was local to the main package; it's not defined here. Nothing is printed. To access the $name variable from the main package, the name of the package, main, is followed by two colons and the variable name. Note that the $ precedes the package name, not the variable. Out of the subroutine, the package main is declared. The subroutine welcome cannot be called unless qualified by its package name. $name is Suzanne in package main. To access a variable from the package friend, the package has to precede the variable name. This causes a switch in namespaces. $name is Suzanne in package main. A new package called birthday is declared. It remains in effect until the block ends—in this case, when the script ends. The $name variable in package birthday is assigned. $name is Beatrice in package birthday. In order to access variables from the previous packages, the package name and a double colon must precede the variable.
|