home | O'Reilly's CD bookshelfs | FreeBSD | Linux | Cisco | Cisco Exam    

Book Home Programming PerlSearch this book

11.2. Creating Modules

Earlier, we said that there are two ways for a module to make its interface available to your program: by exporting symbols or by allowing method calls. We'll show you an example of the first style here; the second style is for object-oriented modules and is described in the next chapter. (Object-oriented modules should export nothing, since the whole idea of methods is that Perl finds them for you automatically, based on the type of the object.)

To construct a module called Bestiary, create a file called Bestiary.pm that looks like this:

package      Bestiary;
require      Exporter;

our @ISA       = qw(Exporter);
our @EXPORT    = qw(camel);    # Symbols to be exported by default
our @EXPORT_OK = qw($weight);  # Symbols to be exported on request
our $VERSION   = 1.00;         # Version number

### Include your variables and functions here

sub camel { print "One-hump dromedary" }

$weight = 1024;

1;
A program can now say use Bestiary to be able to access the camel function (but not the $weight variable), and use Bestiary qw(camel $weight) to access both the function and the variable.

You can also create modules that dynamically load code written in C. See Chapter 21, "Internals and Externals", for details.

11.2.1. Module Privacy and the Exporter

Perl does not automatically patrol private/public borders within its modules--unlike languages such as C++, Java, and Ada, Perl isn't obsessed with enforced privacy. A Perl module would prefer that you stay out of its living room because you weren't invited, not because it has a shotgun.

The module and its user have a contract, part of which is common law and part of which is written. Part of the common law contract is that a module refrain from changing any namespace it wasn't asked to change. The written contract for the module (that is, the documentation) may make other provisions. But then, having read the contract, you presumably know that when you say use RedefineTheWorld you're redefining the world, and you're willing to risk the consequences. The most common way to redefine worlds is to use the Exporter module. As we'll see later in the chapter, you can even redefine built-ins with this module.

When you use a module, the module typically makes some variables or functions available to your program, or more specifically, to your program's current package. This act of exporting symbols from the module (and thus importing them into your program) is sometimes called polluting your namespace. Most modules use Exporter to do this; that's why most modules say something like this near the top:

require Exporter;
our @ISA = ("Exporter");
These two lines make the module inherit from the Exporter class. Inheritance is described in the next chapter, but all you need to know is our Bestiary module can now export symbols into other packages with lines like these:
our @EXPORT    = qw($camel %wolf ram);              # Export by default
our @EXPORT_OK = qw(leopard @llama $emu);           # Export by request
our %EXPORT_TAGS = (                                # Export as group
                     camelids => [qw($camel @llama)],
                     critters => [qw(ram $camel %wolf)],
                   );

From the viewpoint of the exporting module, the @EXPORT array contains the names of variables and functions to be exported by default: what your program gets when it says use Bestiary. Variables and functions in @EXPORT_OK are exported only when the program specifically requests them in the use statement. Finally, the key/value pairs in %EXPORT_TAGS allow the program to include particular groups of the symbols listed in @EXPORT and @EXPORT_OK.

From the viewpoint of the importing package, the use statement specifies a list of symbols to import, a group named in %EXPORT_TAGS, a pattern of symbols, or nothing at all, in which case the symbols in @EXPORT would be imported from the module into your program.

You can include any of these statements to import symbols from the Bestiary module:

use Bestiary;                    # Import @EXPORT symbols
use Bestiary ();                 # Import nothing
use Bestiary qw(ram @llama);     # Import the ram function and @llama array
use Bestiary qw(:camelids);      # Import $camel and @llama
use Bestiary qw(:DEFAULT);       # Import @EXPORT symbols
use Bestiary qw(/am/);           # Import $camel, @llama, and ram
use Bestiary qw(/^\$/);          # Import all scalars
use Bestiary qw(:critters !ram); # Import the critters, but exclude ram
use Bestiary qw(:critters !:camelids);
                                 # Import critters, but no camelids
Leaving a symbol off the export lists (or removing it explicitly from the import list with the exclamation point) does not render it inaccessible to the program using the module. The program will always be able to access the contents of the module's package by fully qualifying the package name, like %Bestiary::gecko. (Since lexical variables do not belong to packages, privacy is still possible: see "Private Methods" in the next chapter.)

You can say BEGIN { $Exporter::Verbose=1 } to see how the specifications are being processed and what is actually being imported into your package.

The Exporter is itself a Perl module, and if you're curious you can see the typeglob trickery it uses to export symbols from one package into another. Inside the Export module, the key function is named import, which performs the necessary aliasing to make a symbol in one package appear to be in another. In fact, a use BestiaryLIST statement is exactly equivalent to:

BEGIN {
    require Bestiary;
    import Bestiary LIST;
}
This means that your modules don't have to use the Exporter. A module can do anything it jolly well pleases when it's used, since use just calls the ordinary import method for the module, and you can define that method to do anything you like.

11.2.1.1. Exporting without using Exporter's import method

The Exporter defines a method called export_to_level, used for situations where (for some reason) you can't directly call Exporter's import method. The export_to_level method is invoked like this:

MODULE->export_to_level($where_to_export, @what_to_export);
where $where_to_export is an integer indicating how far up the calling stack to export your symbols, and @what_to_export is an array listing the symbols to export (usually @_).

For example, suppose our Bestiary had an import function of its own:

package Bestiary;
@ISA = qw(Exporter);
@EXPORT_OK = qw ($zoo);

sub import {
    $Bestiary::zoo = "menagerie";
}
The presence of this import function prevents Exporter's import function from being inherited. If you want Bestiary's import function to behave just like Exporter's import function once it sets $Bestiary::zoo, you'd define it as follows:
sub import {
    $Bestiary::zoo = "menagerie";
    Bestiary->export_to_level(1, @_);
}
This exports symbols to the package one level "above" the current package. That is, to whatever program or module is using the Bestiary.

11.2.1.2. Version checking

If your module defines a $VERSION variable, a program using your module can ensure that the module is sufficiently recent. For example:

use Bestiary 3.14;   # The Bestiary must be version 3.14 or later
use Bestiary v1.0.4; # The Bestiary must be version 1.0.4 or later
These are converted into calls to Bestiary->require_version, which your module then inherits.

11.2.1.3. Managing unknown symbols

In some situations, you may want to prevent certain symbols from being exported. Typically, this applies to modules that have functions or constants that might not make sense on some systems. You can prevent the Exporter from exporting those symbols by placing them in the @EXPORT_FAIL array.

If a program attempts to import any of these symbols, the Exporter gives the module an opportunity to handle the situation before generating an error. It does this by calling an export_fail method with a list of the failed symbols, which you might define as follows (assuming your module uses the Carp module):

sub export_fail {
    my $class = shift;
    carp "Sorry, these symbols are unavailable: @_";
    return @_;
}
The Exporter provides a default export_fail method, which simply returns the list unchanged and makes the use fail with an exception raised for each symbol. If export_fail returns an empty list, no error is recorded and all the requested symbols are exported.

11.2.1.4. Tag-handling utility functions

Since the symbols listed within %EXPORT_TAGS must also appear in either @EXPORT or @EXPORT_OK, the Exporter provides two functions to let you add those tagged sets of symbols:

%EXPORT_TAGS = (foo => [qw(aa bb cc)], bar => [qw(aa cc dd)]);

Exporter::export_tags('foo');     # add aa, bb and cc to @EXPORT
Exporter::export_ok_tags('bar');  # add aa, cc and dd to @EXPORT_OK
Specifying names that are not tags is erroneous.



Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.











??????????????@Mail.ru