Wednesday, December 3, 2014

Using Exporter in a Perl module

The Exporter module makes it easy for another module to define which functions are exported into the other module's users' namespace.

Here's a simple module to demonstrate that

package SomeModule; use warnings; use strict; use Exporter; use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS); @ISA = qw(Exporter); $VERSION = 1; @EXPORT = qw(exp_one exp_two); @EXPORT_OK = qw(ok_one ok_two ok_three ok_four); %EXPORT_TAGS = ('all' => [ ( @EXPORT, @EXPORT_OK) ], 'some' => [ qw(ok_one ok_three exp_two) ] ); sub exp_one { return 'exp_one'; } sub exp_two { return 'exp_two'; } sub ok_one { return 'ok_one'; } sub ok_two { return 'ok_two'; } sub ok_three { return 'ok_three';} sub ok_four { return 'ok_four'; } 1;

And here's a script that uses SomeModule:

use warnings; use strict; use feature 'say'; use SomeModule; say exp_one(); say exp_two(); # say ok_one();

This script can call exp_one and exp_two from SomeModule because these two functions are listed in @EXPORT. Functions listed in @EXPORT are by default exported into the user's namespace.

ok_one, on the other hand, cannot be called directly as it is not listed in @EXPORT. It can, however, be called so SomeModule::ok_one().

Here's another script:

use warnings; use strict; use feature 'say'; use SomeModule qw(ok_one ok_two); # say exp_one(); say ok_one(); say ok_two();

Now, I specify the identifiers I want to have imported into my namespace (qw(ok_one ok_two)). Accordingly, I can call these.

I cannot call exp_one (which I could call in the first script), because as soon as I begin specifying identifiers to be exported I need to specify all of them.

Of course, it will soon be tiresome to always indicate which functions I want to have imported. Therefore, I can define tags with the %EXPORT_TAGS hash that groups multiple identifiers under a tag. For example, the tag all imports all functions. In my case, I just used the combined values of @EXPORT and @EXPORT_OK. This is demonstrated with the third script:

use warnings; use strict; use feature 'say'; use SomeModule (':all'); say exp_one(); say ok_one(); say ok_two();

Lastly, I can import some functions, too:

use warnings; use strict; use feature 'say'; use SomeModule (':some'); # say exp_one(); say ok_one(); say exp_two();

No comments:

Post a Comment