HTML CSS PHP PERL

Another statement: our

 
Previous Table of Contents Next

Another statement: our

Within a package, if you want to use a global (package) variable without prefixing the package name, use the our statement. The our statement allows the package variable name to be used within the module without being fully qualified (as shown in Listing 17.5), and visible outside of the package if it's fully qualified.

Listing 17.5. The our Statement

1:  #!/usr/bin/perl w

2:

3:  use strict;

4:  our $max = 15;

5:

6:  sub read_max {

7:      my $counter = 0;

8:

9:      while(<DATA>) {

10:         my $line = $_;

11:         if ($counter++ < $our) {

12:             print $line

13:         }

14:     }

15: }

16: read_max();


Forcing Your Names on Others

There is one small difference between the File::Find module from Hour 14 and the statistics module from Listing 17.1 (beyond the obvious): File::Find gave the program a find function that wasn't fully qualified. In other words, for convenience, the module author of File::Find decided that instead of forcing everyone to write


use File::Find;

File::Find::find \&wanted, 'documents';


users of the module could just write


use File::Find;

find \&wanted, 'documents';


How did File::Find make its find subroutine part of your program? File::Find uses a special module called Exporter to take subroutine names like find and inject them into the main package so your program can see them.

To make your statistics module do the same thing, just add a little code to the beginning as shown in Listing 17.6.

Listing 17.6. Statistics Program with Function Name Export

1:  #!/usr/bin/perl -w

2:  use strict;

3:  package TYPStats;

4:

5:  use Exporter;

6:  our @ISA=qw(Exporter);

7:  our @EXPORT=qw(mean median);

8:

9:  sub mean {

10:        my(@data) = @_;

11:        my $sum;

12:        $sum += $_ foreach(@data);

13:        return @data ? ($sum / @data) / 0;

14: }

15: sub median {

16:       my(@data)=sort { $a <=> $b} @_;

17:       if (scalar(@data) % 2) {

18:               return($data[@data / 2]);

19:        }

20:       return(mean($data[@data / 2],

21:             $data[@data / 2 - 1]));

22: }

23: 1;


Everything is exactly as it was before, except for the following:

Line 5: You're using the Exporter module. The Exporter module requires that you declare a couple of package variables to make it work.

Line 6: The @ISA variable is needed by Exporter to do its work. Notice that @ISA is being declared explicitly to be in this package by using the our statement.

Line 7: The @EXPORT variable contains a list of subroutine names and variables that you want to allow to be imported into the calling program. In this case, you're exporting the subroutines mean and median.

Now you can call mean without any qualification:


print mean(3, 6, 10, 51, 3, 99);


Exporting your module's names into other people's packages usually isn't good form. You're causing new functions or variables to suddenly appear in someone's program. If they had written a function called mean and you're importing a mean function, which one gets run? Writing modules that stomp on other program's variables is called namespace pollutionavoid this whenever possible.

By the Way

The particular combination of statements used in Listing 17.6 (package, use, ISA, EXPORT, and so on) is put together differently by different module authors and documentation. Some will use the keyword our instead of using fully qualified names, some will use require for Exporter, and others will not. There is more than one way to do it.


It is possible to make names visible, but only if the use program wants them. Instead of using @EXPORT, use @EXPORT_OK. This offers the name to the calling program, but only if it wants the names. The example in the following snippet offers up two function names, mean and median.


package TYPStats;



use Exporter;

our @ISA=qw(Exporter);

our @EXPORT=qw();

our @EXPORT_OK=qw(mean median);


If you use the module like this:


use TYPStats;


the calling program will not have a mean subroutine name imported for it. It will still have to use the fully qualified name TYPStats::mean. If you use the module like this:


use TYPStats qw(mean);


you get a mean subroutine, but not medianthat is still accessible by the fully qualified name, though. If you want both, use both:


use TYPStats qw(mean median);


Now mean and median have both been imported into your program to be used without the fully qualified name.

    Previous Table of Contents Next
    © 2000- NIV