Документация
HTML CSS PHP PERL другое

Section 15.5.  Exporting in a Primarily OO Module

 
Previous
Table of Contents
Next

15.5. Exporting in a Primarily OO Module

As seen earlier, the normal means of using an object-oriented module is to call class methods and then methods against instances resulting from constructors of that class. This means that an OO module typically exports nothing, so we'll have:

package My::OOModule::Base;
our @EXPORT = (  ); # you may even omit this line
use base qw(Exporter);

What if we then derive a class from this base class? The most important thing to remember is that the import method must be defined from the Exporter class, so we add it like so:

package My::OOModule::Derived;
use base qw(Exporter My::OOModule::Base);

However, wouldn't the call to My::OOModule::Derived->import eventually find its way up to Exporter via My::OOModule::Base? Sure it would. So we can leave that out:

package My::OOModule::Derived;
use base qw(My::OOModule::Base);

Only the base classes at the top of the tree need to specify Exporter, and only when they derive from no other classes.

Please be aware of all the other reserved method names that can't be used by your OO module (as described in the Exporter manpage). At the time of this writing, the list is export_to_level, require_version, and export_fail. Also, we may wish to reserve unimport because Perl will call that routine when we replace use with no. That use is rare for user-written modules, however, although it often shows up with pragmas such as strict and warnings.

Even though an OO module typically exports nothing, we might choose to export a named constructor or management routine. This routine typically acts a bit like a class method, but we want users to call it as a regular subroutine.

One example is the LWP library, available on the CPAN as part of the libwww-perl distribution. The URI::URL module, now deprecated and replaced by the URI module, deals with universal resource identifiers, most commonly seen as URLs such as http://www.gilligan.crew.hut/maps/island.pdf. We can construct a URI::URL object as a traditional object constructor with:

use URI::URL;
my $u = URI::URL->new('http://www.gilligan.crew.hut/maps/island.pdf');

The default import list for URI::URL also imports a url subroutine, which we can use as a constructor as well:

use URI::URL;
my $u = url('http://www.gilligan.crew.hut/maps/island.pdf');

Because this imported routine isn't a class method, we don't use the arrow method call to invoke it. Also, the routine is unlike anything else in the module: it gets no initial class parameter. Even though normal subroutines and method calls are both defined as subroutines in the package, the caller and the author must agree as to which is which.

The url convenience routine was nice, initially. However, it clashed with the same-name routine that CGI.pm TRied to export as well, leading to interesting errors (especially in a mod_perl setting). The module that got there last won. (The modern interface in the URI module doesn't export such a constructor.) Prior to that, in order to prevent a crash, we had to remember to bring it in with an empty import list:

use URI::URL (  );        # don't import "url"
my $u = URI::URL->new(...);


Previous
Table of Contents
Next
© 2000- NIV