Home » Tutorials » Modules |
Shlomi Fish
Perl supports both packages (or namespaces) and modules.
A module is a file that contains related functions and variables. It can be re-used by several scripts as well as other modules. Modules can be loaded at run-time and then their functions can be called. This goes a long way to provide code encapsulation and avoid duplicate code.
Packages are namespaces in which functions and variables can be placed. A module or even a script can contain several packages. Two different packages can each contain functions or variables with the same identifiers, without these interfering with one another. This helps make sure that there are no clashes in the code.
It is generally a good idea for a module to contain identifiers only inside packages under the same name. That way one can be sure that they won't clash with those of other modules, including those of third parties.
Furthermore, packages are the basis for Perl's system of Object Oriented Programming.
In this tutorial we'll cover:
Declaring a Package
Importing Modules and their Functions
BEGIN and END
The "main" Namespace
Difference between Namespaces and Modules
In order to designate that code belongs to a particular namespace you
should use the package
directive. For instance, if you want your namespace
(and module) name to be "MyModule" your file should look something like
this:
# This is the file MyModule.pm # package MyModule; use strict; sub a_function { print "Hello, World!\n"; } 1;
Note that a module has to return a true value to the Perl interpreter, so
it's customary to end your module file with a 1;
(see perldoc -f require
for why this is so).
A namespace may contain sub-namespaces. To separate namespace components,
use the ::
separator. For example:
# This is the file Hoola/Hoop.pm # package Hoola::Hoop; my $counter = 0; sub get_counter { return $counter++; } 1;
A module is a separate file that may contain one or more different
namespaces. That file is found in a place that corresponds to the module's
name. To find the filename of the module relative to the script's directory,
replace every ::
with a slash and add ".pm" to the name of the
last component.
For instance: the MyModule
module will be found in the file
"MyModule.pm"; the Hello::World
module will be found in the
file "World.pm" under the Hello sub-directory; etc.
In order to have access to a module from within your script (or from
within another module) you can use the use
directive followed
by the name of the module as it is deduced from its path. Here's
an example: assume that the file "MyModule.pm" contains:
# This is the file MyModule.pm # package MyModule; use strict; sub a_function { print "Hello, World!\n"; } 1;
And this is your script:
#!/usr/bin/perl use MyModule; # Notice that we use "::" to call the function out of the module. MyModule::a_function();
That way, the program will print "Hello, World!" on the screen.
++ Reviewed thru to here ++
As could be seen from the last example, once the module has been
use
'd, its functions can be invoked by typing the
full path of the package followed by ::
and followed by
the function name.
Note that if you are in package Foo
and you are trying to access
functions from package Foo::Bar
, then typing Bar::my_func()
will not do. You have to type the full path of the module.
(Foo::Bar::my_func()
in our case)
It is possible to make a functions of your module automatically available in any other namespace or script that uses it. To do so one needs to type the following code fragment near the beginning of the module:
use Exporter; use vars qw(@ISA @EXPORT); @ISA=qw(Exporter); @EXPORT=("function1", "function2", "function3");
What this fragment does is make the module inherit the Exporter
module which is a special Perl module that can export symbols. Then
it declares the special variable @EXPORT
which should be filled
with all the functions that one wishes to export.
Here is an example which has a module called "Calc" and a script that uses it:
# File: Calc.pm # package Calc; use strict; use Exporter; use vars qw(@ISA @EXPORT); @ISA=qw(Exporter); @EXPORT = ("gcd"); # This function calculates the greatest common divisor of two integers sub gcd { my $a = shift; my $b = shift; if ($b > $a) { ($a, $b) = ($b , $a); } while ($a % $b > 0) { ($a, $b) = ($b, $a % $b); } return $b; } 1; <CODE> #!/usr/bin/perl use strict; use Calc; my $a = 200; my $b = 15; print "gcd(\$a,\$b) == " , gcd($a,$b), "\n";
As you can see, the script invokes the "gcd" function of the "Calc" module
without having to invoke it with Calc::gcd()
. Exporting functions
like that should be used with care, as the function names may conflict with
those of the importing namespace.
It is also possible to import or export the global variables of different
modules. However, such variables need to be declared using the
use vars qw($myvar1 @myvar2)
construct.
Here's an example for a module that defines a variable and another one that access it:
# This file is MyVar.pm # package MyVar; use strict; # Declare a namespace-scoped variable named $myvar. use vars qw($myvar); sub print_myvar { print $myvar, "\n"; } 1;
#!/usr/bin/perl use strict; use MyVar; $MyVar::myvar = "Hello"; MyVar::print_myvar(); $MyVar::myvar = "World"; MyVar::print_myvar();
There are two special code blocks for perl modules - BEGIN
and
END
. These blocks are executed when a module is first loaded,
and when the perl interpreter is about to unload it, respectively.
Here's an example for a logging module that makes use of this facility:
# File : MyLog.pm # package MyLog; BEGIN { open MYLOG, ">mylog.txt"; } sub log { my $what = shift; # Strip the string of newline characters $what =~ s/\n//g; # The MYLOG filehandle is already open by virtue of the BEGIN # block. print MYLOG $what, "\n"; } END { close(MYLOG); } 1;
One can access the main namespace (i.e, the namespace of the script),
from any other namespace by designating main
as the
namespace path. For instance, main::hello()
will invoke
the function named "hello" in the script file.
Usually, the "main" part can be omitted and the symbols be accessed
with the notation of ::hello()
alone.
A namespace or package is a container for MyPackage::MySubPack::my_func()
symbols.
A module, on the other hand, is a file that can contain any number of namespaces, or simply drop everything into the current namespace (although it shouldn't).
It is possible to switch to other packages using the package
statement. However, you then have to remember not to use
them, because Perl will look for a file corresponding to that name.
A module
can put itself in a completely different namespace than its designated module name. (e.g: a module loaded with use TheModule;
can declare all of its identifiers in the CompletelyDifferentPackage
namespace.)
If this is a bit confusing, then it should be.
perldoc perlmod perldoc perlmodlib Writing Perl Modules for CPAN - Sam Tregar Perl for Perl Newbies - Lecture Series