I've recently been wrangling with some Perl code for a project at work, and have been putting together a Perl module that includes a number of common functions that I need. As such, I had to remind myself how to create a Perl module. During my initial development, I ran into a number of problems, but I eventually worked through all of them. In the hopes of helping myself remember how to do this, and to help any other burgeoning Perl developers, I've written the following little guide. Hopefully it will help shed some light on this subject.
Let me preface this guide with two important statements:
- I'm not aiming to show you how to create a module for distribution. Most of the other tutorials cover that topic in depth.
- I am going to assume that you have a working knowledge of Perl.
To start, let's take a look at our sample module:
package MyPackage;
use strict;
use warnings;
require Exporter;
our @ISA = ("Exporter");
our %EXPORT_TAGS = ( 'all' => [ qw(sayHello whoAreYou $firstName
%hashTable @myArray) ] );
our @EXPORT_OK = (@{ $EXPORT_TAGS{'all'} });
our @EXPORT = qw();
our $firstName = "Jonah";
our $lastName = "Bishop";
our %hashTable = { a => "apple", b => "bird", c => "car" };
our @myArray = ("Monday", "Tuesday", "Wednesday");
sub sayHello
{
print "Hello World!\n";
}
sub whoAreYou
{
print "My name is $firstName $lastName\n";
}
1;
We start out by declaring our package name with the package
keyword. Special Note: If you intend on having multiple modules, and you use the double colon (::)
separator, you're going to need to set up your directory structure correspondingly. For example, if I had two modules, one named Jonah::ModuleOne
and another named Jonah::ModuleTwo
, I would need to have a folder named Jonah
, inside of which would live the code to my two modules.
I next enable the strict
and warnings
pragmas, since that's good programming practice. Lines 5 and 6 are standard to virtually all Perl modules. First, we require inclusion of the standard Exporter module, then we indicate that our module inherits from said Exporter (the @ISA (is a) array is what sets this).
Line 8 is where things get interesting. We need to specify what symbols we want to export from this module. There are a number of ways of doing this, but I have chosen to use the EXPORT_TAGS
hash. Special Note: This is a hash, not an array! I recently spent about an hour trying to debug a strange error message, and it all stemmed from the fact that I had accidentally created this as an array.
The EXPORT_TAGS
hash gives us a means of grouping our symbols together. We essentially associate a label with a group of symbols, which makes it easy to selectively choose what you want to import when using the module. In this example, I simply have a tag named 'all' which, as you might guess, allows me to import all of the specified symbols I provide in the associated qw()
list. Note that you must precede exported variable names with their appropriate character: $ for scalars, @ for arrays, and % for hashes. Exported subroutines don't need to have the preceding & character, but it doesn't hurt if you put it there.
Line 10 shows the EXPORT_OK
array. This array specifies the symbols that are allowed to be requested by the user. I have placed the EXPORT_TAGS{'all'}
value here for exporting. I will show how to import this symbol into a script in just a moment. Line 11 is the EXPORT
array, which specifies the symbols that are exported by default. Note that I don't export anything by default. Special Note: It is good programming practice to not export anything by default; the user should specifically ask for their desired symbols when they import your package.
Lines 13 through 27 should be self explanatory. We set up two scalar variables, $firstName
and $lastName
, as well as a hash table and an array. Note that we precede all variables with the our
declaration, which puts this variable into the global scope for the given context. Since we're using the strict
pragma, we need these our
declarations; otherwise we'd get some compilation errors.
Line 29 is very important and can easily be forgotten. When a Perl module is loaded via a use
statement, the compiler expects the last statement to produce a true value when executed. This particular line ensures that this is always the case.
Now that we've taken a look at the module, let's take a look at a script that uses it:
#!/usr/bin/perl
use strict;
use warnings;
use MyPackage qw(:all);
sayHello();
whoAreYou();
print "$lastName\n"; # WRONG!
print $MyPackage::lastName . "\n"; # RIGHT!
Most of this should be pretty clear. Note, however, how we import the module on line 4. We do the typical use MyPackage
statement, but we also include the symbols we want to import. Since we didn't export anything by default, the user has to explicitly ask for the desired symbols. All we exported was a tag name, so we specify it here. Note the preceding colon! When you are importing a tag symbol, it must be preceded by a single colon. This too caused me a great deal of frustration, and it's a subtlety that's easily missed.
One other interesting note: on line 9, we try to print the $lastName
variable. Since we never exported that particular variable in our module, referencing it by name only will result in an error. The correct way to access the variable, even though it wasn't exported, is shown on line 9. You must fully qualify non-exported symbols!
Hopefully this quick little guide has made things a little clearer for you. If for no other reason, it will help me remember these subtleties of Perl programming. :-)