Item 42: Understand packages and modules.


Perl modules are really a specialized form of Perl packages . In this Item we will discuss packages, then the specializations that make a package a module.

Packages

A Perl package is a namespace. It's that simple. Whether or not you are familiar with packages, if you have written a Perl program, you have already used at least one: the main package. By default, all variables created in a Perl program are part of the main package.

To refer to a variable in another package, prefix its name with the package name, followed by two colons (called a " qualified name"). Two colons without any package name is shorthand for the main package:

 $a = 'Testing';  print "main::a = $main::a\n"; 

Assign to $a , a.k.a. $main::a .

main::a = Testing

 $foo::a = 'one two three';  print "$main::a $foo::a\n";  print "$::a $foo::a\n"; 

Assign to $foo::a .

Testing one two three

Testing one two three

The package directive changes the current default package. It remains effective until the end of the current block or file:

Continued from above:

 {    package foo; 

Begin a new scope.

foo is now the default package.

 $a = 'four five six';    print "$::a $a\n";  } 

Assign to $a , a.k.a. $foo::a .

Testing four five six

 print "$a $foo::a\n"; 

Testing four five six , since $a now means $main::a again.

Packages can be nested. For example, $foo::bar::bletch is a variable named bletch nested inside a package named bar inside a package named foo . However, qualified names always must appear in fullyou cannot use $bar::bletch to refer to the above variable bletch even if the default package is foo .

Packages are implemented as symbol tables, which are just ordinary Perl hashes with a special purpose (see Item 55). The name of a package symbol table is the package name followed by two colons, for example %foo:: and %:: (the main package's symbol table). Although occasions when you should directly manipulate symbol tables are rare, you can, for example, import names from one package into another:

 package foo;  ($a, $b, $c, $d) =    qw(testing one two three);  sub Bar { 3 }; 

Define some variables in package foo .

Define subroutine $foo::Bar .

 package main;  @::{qw(a b c Bar)} =    @foo::{qw(a b c Bar)};  print "$a $b $c ", Bar(), "\n"; 

Import a , b , c and Bar from foo .

testing one two 3

A possibly unexpected side effect of this kind of manipulation is that it aliases variables in one package to another. In the example above, $main::a and $foo::a now refer to the same thing:

Continued from above:

 $foo::a = 'TESTING'; 

Change value of $foo::a .

 print "$a $b $c ", Bar(), "\n"; 

TESTING one two three

$main::a is aliased to $foo::a .

You can see more of this type of Perl "magic" in Item 55. Remember that my variables are never in any package (see Item 23).

Modules

A Perl module is a package that meets certain requirements. To be a Perl module, a package must:

  • be contained in a separate file whose name ends in .pm ("Perl module"), [1]

    [1] Old-style "Perl libraries" were contained in files ending in .pl . You may see these used in older code from time to time. There is no reason to write or use this type of library any more, except when necessary to maintain existing software.

  • define an import methodusually done by subclassing the Exporter module, [2] and

    [2] Why does the Exporter class import things? Hmm. This is another one of those Perl enigmas that it is better not to contemplate deeply.

  • define a (possibly empty) list of symbols that are automatically exported, as well as a (possibly empty) list of symbols that can be exported on request. [3]

    [3] This is a convention, not a requirement. But it is rarely broken.

The purpose of a module is to implement reusable, modular functionality. Generally , modules define subroutines and/or Perl classes (see Item 49). Modules can also define variables (scalars, arrays, etc.). They can perform actions at startup and can even alter language syntax or semantics (see Item 37).

Modules are generally stored in a library directory that is accessible via Perl's default include path (see Item 43). Exactly what that location is will vary depending upon your installation, but a typical location would be something like /usr/local/lib/perl5/ .

Modules can be nested. Nested modules are stored in a nested directory/file structure. For example, given an installation whose libraries are stored in /usr/local/lib/perl5/ , the File::Basename module will most likely be found in /usr/local/lib/perl5/File/Basename.pm .

Using modules

It's easy to put a module to work for you. Just "use" the modulewith Perl's use directive. The use directive loads a module and imports the subroutines and other symbols that are exported from that module by default:

 use SomeModule; 

Load the module SomeModule.pm and do default imports.

For example, suppose you have just learned about the File::Basename module. Suppose you would like to use the dirname subroutine that it defines. Here's one possibility:

 use File::Basename; 

Load File::Basename module exports dirname , basename , etc.

 setpwent;  while (@pwinfo = getpwent) {    my ($usr, $sh) = @pwinfo[0, -1];    if ($sh and        dirname($sh) ne "/bin") {      print "shell $sh for $usr?\n"    }  } 

Loop through password info looking for shells not beginning with /bin .

The use directive can take a list of arguments. These are passed to the module's import method, and, assuming that the module's import method has the usual semantics, this list should be a list of symbolssubroutine names and the likethat are to be imported into the current package. For example, if you wish to import only dirname and basename from File::Basename , you can invoke it as:

 use File::Basename qw(dirname basename); 

If you wish to import no symbols at all, pass an explicit empty list:

 use File::Basename (); 

Remember that Perl doesn't prevent you from accessing symbols (other than my variables) that are not in the current package. If you use a module but choose not to import any symbols from it, you can always refer to them with their fully qualified names:

 use File::Basename (); 

Load File::Basename.pm but import no symbols.

 print "Gimme a pathname: ";  $file = <>;  $dir =    File::Basename::dirname($file);  print "dir = $dir\n"; 

Now we have to call dirname the long way.



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