WebReference.com - Perl Module Primer (4/5)

Perl Module Primer

On the previous page, we accessed the hello_message routine
of our new module via this statement:

print SayHello::hello_message()."\n";

Since we cannot access a sub routine in another namespace (recall from page
2 that a separate namespace is defined every time we use the package
declaration) directly, we must instead use a qualified name to access
our module's symbols (i.e. variables, or sub routines). To qualify a variable
or sub routine reference, simply prefix it with the name of the package
it is in, followed by a double colon. Thus, SayHello::hello_message()
is one way we can reference the hello_message routine from outside
the SayHello module. (We can also access the routines by importing
them; more on that a little further down this page.)

While they may not look familiar to you, you are already using
packages in your existing scripts. The fact is that all Perl
scripts assume (until you tell them otherwise via a package
declaration) that the variables and sub routines defined within them
belong to the package main. Thus, in our earlier foobar
example, we could also have written:

$myVariable="foobar";
print $main::myVariable;

with the same result. Note that when we refer to variables in this
fashion, we place the $ sign on the left of the package declaration,
and not next to the variable name:

$myVariable="foobar";
print main::$myVariable; # incorrect

This rule is true when you reference your package variables and subroutines
in your new modules, too. If we had moved our module to the Local sub
directory, as we discussed on the previous page, then the reference would look
like this:

print Local::SayHello::hello_message()."\n";

Watch Out For my

You can access variables in modules via their package qualifications, the
same way you access the sub routine as in the example above. But note that
if you define the variable with the keyword my when you create it
within the module, you will not be able to access it from outside the module.
Just like my variables in local sub routines, the my variables
in modules only exist directly within the module itself, subject to
the normal scoping rules for my. Using the qualified form of the variable
name as above will not retrieve the variable for you.

If you must access a module variable from outside the package you are
declaring it in, then you can declare it using the our function (available
in later Perl versions, I believe 5.6 and later), in effect creating a
package variable that is then accessible to all
other packages via a qualified name. A good example of this would be the
$VERSION variable; which authors include by convention (and is
therefore recommended) in most Perl modules, and which is automatically
used by various Perl utilities. Let's add a $VERSION variable to
our module and access it from our main script:

#!/usr/bin/perl
use strict;
use SayHello;
print "You are using version: $SayHello::VERSION of SayHello.\n";
print SayHello::hello_message()."\n";

Note that we added a use strict pragma to both code
segments. This does not prevent us from accessing the
our variable, while still helping us to write cleaner code. We could
also have defined the $VERSION variable by fully qualifying
it; i.e., $SayHello::VERSION = 0.10;. Note also that
the new $hello_string variable is a my variable, and is
therefore not accessible from the main script. But that doesn't mean
we can't use it in the module itself! Our hello_message
routine now returns the value of this variable; and in fact, this is a
recommended way for you to provide access to the variables within
your modules that should be accessible from other packages.
Simply define a separate routine--or routines--within the module that
will return (and perhaps set, if warranted) the value of the variable, and then the
caller can access the variable through that routine. This allows you
to separate the logic from within the modules from the logic outside
of the modules, while still allowing access to those module components
that need to be accessed from the outside world.

Before we move on, note one further use for the $VERSION variable.
If you load the module like this:

use SayHello 0.20;

then Perl will automatically check the version number of the module
that is loaded and will not continue unless it (the version number stored
in the module) is greater than or equal to the version number specified in the
use statement.

Exporting

On the previous page, we mentioned that one side effect of loading a module
into our script with use is that the import routine of the
module is automatically called. This functionality provides you with a way to
set certain module variables and sub routines such that the calling program
can directly import them into their own namespaces; and therefore access them
directly without the qualified naming structure. The specifics of how
this is actually accomplished is just a bit outside the scope of this article,
but to see what it would look like, let's alter our module and script to allow
the hello_message sub routine to be exported as needed:

#!/usr/bin/perl
use strict;
use SayHello qw(hello_message);
print "You are using version: $SayHello::VERSION of SayHello.\n";
print hello_message()."\n";

Note that in this case, we did not need to qualify our
hello_message call; since we imported it via

use SayHello qw(hello_message);

Again, the above code is just a bit outside the scope of where I want to go
with this article, but here's some basic information about what's going on behind
the scenes:

require Exporter;
allows us to utilize the export facilities in the standard Perl module Exporter.
specifically, the import routine in Exporter will be
called each time our module is used.

our @ISA = qw(Exporter);
informs Perl that our module will inherit functions from the Exporter
module. This is how the import module of Exporter is called
when our module is used. Since our module does not have an import
module, Perl searches the modules that we inherit from, and finds the import
module in Exporter instead.

our @EXPORT_OK = qw(hello_message);
a list of those variable names that we designate as exportable to scripts that
use our module.

use SayHello qw(hello_message);
our new use statement includes a list of those module symbols that we want
to import into our namespace. Note that this does not prevent us from continuing to
access $VERSION via its qualified name; even though it is not in the
@EXPORT_OK array.

We could also have automatically exported symbols (without having to specifically
request them in the use statement) by including the symbols to export by
default in the @EXPORT array. However, doing this would automatically
add symbols into the calling script by default; which is generally not a good thing to
do. Remember, you don't know what variables and symbol names the calling script
may be using; the best course is to simply stay out of their code and let them pull
in the symbols of your module that they need as they need them.

Armed with this basic information, you should have all you need to start
writing helpful modules for your own projects, and I encourage you to do so.
But there remains much to be discussed about module usage that is not
covered in this basic tutorial. On the next page, we'll
conclude by looking at some of the module-related topics you may want to
continue pursuing on your own.