CGI and Perl

Listing 2.2. Using the simple extension module.

use Foo;
 $loaded = FooLoad("FooFile");
 Foo::Get($loaded);
 Foo::Print($loaded);

Note how you are able to invoke the FooLoad() routine directly, but the Print() and Get() routines have to be invoked through the fully qualified name. Exporting all the methods from a module is enticing, but the practice is generally discouraged. A module that exports its methods into your program's namespace by default should have a valid reason for doing so. The module that does so takes the chance that one or more of its method or variable names will collide with a name that you are already using, potentially causing confusion and debugging headaches. In the preceding Foo module, the generically named Get() and Print() routines could easily cause such problems. Thus, they're exported through the @EXPORT_OK array and are loaded into the main:: namespace only upon request or invoked as shown via the full name. The general recommendation for using Perl modules is for you to access their methods through the full name and import nothing by default, unless you're going to subclass the module.

An even better way, in my opinion, is to use a blessed reference to the package to invoke the method. Of course, this assumes that some sort of new() method has been defined or inherited in the package to return a blessed reference to the package, or that you've explicitly blessed a reference into the package. Because the Foo module doesn't have a new() method, you'll need to use the latter technique, as shown in Listing 2.3.

Listing 2.3. Using a blessed reference to invoke methods from the Foo module.

use Foo;
 my $packageref = {};  # must be a reference
 bless $packageref, Foo; # bless $packageref into the foo package directly
 $loaded = FooLoad("FooFile");
 $newFoo = $packageref->Get($loaded);
 $packageref->Print($newFoo);

This syntax just looks and feels cleaner, in my opinion. But there's more than one way to do it, as always, with Perl.

That wraps up the discussion regarding design and intent of modules and extensions. The following sections deal with the type of module that provides its own subroutines and doesn't load a shared library, which I call a regular module. Most of the WWW modules are of this type. Using Regular Modules Now we return to the Customer package from earlier in this chapter, where we were already doing most of the things discussed up to this point. Add a short POD for brevity, and one additional method, called addstat(), to wind up with what's shown in Listing 2.4.