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

Section 17.5.  Exporting

 
Previous
Table of Contents
Next

17.5. Exporting

Export judiciously and, where possible, only by request.

As with classes (see Chapter 15), modules should aim for an optimal interface, rather than a minimal one. In particular, you should provide any non-fundamental utility subroutines that client coders will frequently need, and are therefore likely to (re-)write themselves.

On the other hand, it's also important to minimize the number of subroutines that are exported by default. Especially if those subroutines have common names. For example, if you're writing a module to support software testing, then you might want to provide subroutines like ok( ), skip( ), pass( ), and fail( ):

    package Test::Utils;

    use base qw( Exporter );
    our @EXPORT = qw( ok skip pass fail );    # Will export these by default

    
    # [subroutine definitions here]

But exporting those subroutines by default can make the module more difficult to use, because the names of those subroutines may collide with subroutine or method definitions in the software you're testing:

    use Perl6::Rules;   # CPAN module implements a subset of Perl 6 regexes
    use Test::Utils;    # Let's test it...

    my ($matched)
        = 'abc' =~ m{ ab {ok 1} d    # Test nested code blocks in regexes
                    | {ok 2; fail}   # Test explicit failure of alternatives
                    | abc {ok 3}     # Test successful matches
                    }xms;

    if ($matched) {
        ok(4);
    }

Unfortunately, both the Perl6::Rules and Test::Utils modules export a fail( ) subroutine by default. As a result, the example test is subtly broken, because the Test::Utils::fail( ) subroutine has been exported "over the top of" the previously exported Perl6::Rules::fail( ) subroutine. So the fail( ) call inside the regex isn't invoking the expected fail( ).

The point is that both modules are behaving badly. Neither of them ought to be exporting a subroutine with a name like fail( ) by default; they should be allowing those subroutines to be exported only by explicit request. For example:


    package Test::Utils;

    use base qw( Exporter );

    our @EXPORT_OK = qw( ok skip pass fail );    
# Can export these, on request

    # [subroutine definitions here]

In that case, both of them would then have to be loaded like so:


    use Perl6::Rules qw( fail );
    use Test::Utils  qw( ok skip );

and there would no longer be a conflict. Or, if they were going to collide, then the conflict would be immediately obvious:


    use Perl6::Rules qw( fail );
    use Test::Utils  qw( ok skip fail );

So make the interface of a module exportable on request, rather than exported by default.

The only exception to this guideline would be a module whose central purpose is always to make certain subroutines available (as IO::Prompt does with the prompt( ) subroutine, or Perl6::Slurp does with slurp( )see Chapter 10). If a module will always be used because programmers definitely want one particular subroutine it provides, then it's cleaner to export that subroutine by default:


    package Perl6::Slurp;

    use base qw( Exporter );

    our @EXPORT = qw( slurp );    
# The whole point of loading this module

                                  # is to then call slurp( )

    Previous
    Table of Contents
    Next
    © 2000- NIV