Skip to content

Perl Packages & Modules

Packages and modules are fundamental to Perl’s design, enabling code organization, reusability, and namespacing.

A package is a distinct namespace in Perl. It allows you to group related variables and subroutines, preventing name collisions with code in other parts of your program or in different modules.

  • A package is essentially a collection of code that resides in its own symbol table (namespace).
  • Namespaces ensure that variables (e.g., $name) in one package do not interfere with variables of the same name in another package.
  • Packages are crucial for building modules, which are self-contained units of reusable code.
  • The package declaration switches the current compilation context to the specified namespace. This effect lasts until another package statement is encountered, or until the end of the current block or file.
  • You can access variables or subroutines from other packages using the :: qualifier (e.g., OtherPackage::some_function(), $OtherPackage::some_variable).

Here’s an example demonstrating different packages within a single file. The special variable __PACKAGE__ holds the name of the current package.

#!/usr/bin/env perl
use strict;
use warnings;
# This is the 'main' package by default
our $i = 1; # Package variable
print "In package: ", __PACKAGE__, ", \$i = $i\n";
package Foo;
# Now we are in the 'Foo' package
our $i = 10; # A different $i, scoped to Foo
print "In package: ", __PACKAGE__, ", \$i = $i\n";
sub bar {
print "Function bar in package Foo reporting: ", __PACKAGE__, "\n";
}
package Bar;
# Now we are in the 'Bar' package
our $i = 20;
print "In package: ", __PACKAGE__, ", \$i = $i\n";
Foo::bar(); # Calling a sub from another package
package main;
# Switching back to the 'main' package
our $i = 100;
print "In package: ", __PACKAGE__, ", \$i = $i\n";
print "Accessing Foo's \$i from main: $Foo::i\n";
print "Accessing Bar's \$i from main: $Bar::i\n";
1; # Modules and packages often end with a true value

When the above code is executed, it produces:

In package: main, $i = 1
In package: Foo, $i = 10
In package: Bar, $i = 20
Function bar in package Foo reporting: Foo
In package: main, $i = 100
Accessing Foo's $i from main: 10
Accessing Bar's $i from main: 20

Perl allows defining special code blocks named BEGIN and END.

BEGIN {
# Code here runs as soon as it's compiled,
# before the rest of the script starts.
}
END {
# Code here runs when the Perl interpreter is exiting,
# after the main script execution finishes or die_handler is called.
}
  • BEGIN blocks are executed immediately after they are fully compiled, even before the rest of the file is parsed. Multiple BEGIN blocks execute in the order they appear.
  • END blocks are executed in reverse order of their appearance, just before the interpreter exits. They run even if the script exits due to an uncaught die.
  • These blocks are particularly useful in modules for setup ( BEGIN ) or cleanup ( END ) tasks.

Example of BEGIN and END blocks:

#!/usr/bin/env perl
use strict;
use warnings;
package MyDemo;
print "Main script execution starts here.\n";
BEGIN {
print "This is inside a BEGIN block. It runs first!\n";
}
END {
print "This is inside an END block. It runs last!\n";
}
BEGIN {
print "This is another BEGIN block. It also runs early!\n";
}
print "Main script execution continues.\n";
1;

When the above code is executed, the output is:

This is inside a BEGIN block. It runs first!
This is another BEGIN block. It also runs early!
Main script execution starts here.
Main script execution continues.
This is inside an END block. It runs last!

A Perl module is a reusable package defined in a library file. By convention, the file name is the same as the package name, with a .pm extension (e.g., package Foo is in Foo.pm). Modules are the primary way to structure and distribute reusable Perl code.

A simple module file, MyUtils.pm, might look like this:

MyUtils.pm
package MyUtils;
use strict;
use warnings;
# This module will export 'greet' by default
require Exporter;
our @ISA = qw(Exporter);
our @EXPORT = qw(greet);
# This function can be exported
sub greet {
my ($name) = @_;
print "Hello, $name!\n";
}
# This function is not exported by default
sub internal_helper {
print "This is an internal helper.\n";
}
1; # Important: Modules must end with a true value.

Key points about Perl modules:

  • Modules promote code organization and reusability.
  • The use and require statements are used to load modules.
  • Both use and require search for module files in the directories listed in the @INC array.
  • use ModuleName; is equivalent to BEGIN { require ModuleName; ModuleName->import(); }. It loads the module at compile time and calls its import method (often inherited from Exporter to bring symbols into the caller’s namespace).
  • require ModuleName; loads the module at runtime and does not call import automatically.
  • The 1; at the end of a module file ensures that its compilation (and loading via require or use) evaluates to a true value, indicating success.

You can load a module using require. When you do this, you typically need to fully qualify the names of subroutines you call from the module:

#!/usr/bin/env perl
use strict;
use warnings;
# Assuming MyUtils.pm is in a directory in @INC
require MyUtils;
MyUtils::greet("World"); # Must use full package name
# MyUtils::internal_helper(); # This would also work if called explicitly

use is more common for loading modules. It loads the module at compile time and, by default, calls the module’s import method. If the module uses Exporter, this can bring specific subroutines (and variables) into your current namespace, allowing you to call them without the package qualifier.

#!/usr/bin/env perl
use strict;
use warnings;
# Assuming MyUtils.pm is in a directory in @INC
use MyUtils; # Loads MyUtils.pm and calls MyUtils->import()
greet("Again"); # 'greet' was exported, so no 'MyUtils::' needed
# internal_helper(); # This would be an error, as it wasn't exported.

To make symbols available for import, a module typically uses the Exporter module:

# Inside MyUtils.pm
package MyUtils;
use strict;
use warnings;
require Exporter;
our @ISA = qw(Exporter); # Inherit from Exporter
our @EXPORT = qw(greet); # Export 'greet' by default
our @EXPORT_OK = qw(another_func); # Export 'another_func' on request
our %EXPORT_TAGS = (
all => [ qw(greet another_func) ],
extra => [ qw(another_func) ]
);
sub greet { my ($name) = @_; print "Hello, $name from MyUtils!\n"; }
sub another_func { print "This is another_func from MyUtils!\n"; }
1;

Then, a script can use it like this:

#!/usr/bin/env perl
use strict;
use warnings;
use MyUtils; # Imports 'greet' (from @EXPORT)
greet("Default User");
# To import 'another_func' as well:
# use MyUtils qw(greet another_func);
# or
# use MyUtils qw(:all); # Imports everything in @EXPORT and %EXPORT_TAGS{all}
# another_func();

Creating a Modern Perl Module Distribution

Section titled “Creating a Modern Perl Module Distribution”

While h2xs was historically used, modern Perl development relies on more advanced tools for creating, building, testing, and distributing modules. These tools help manage dependencies, automate testing, and follow CPAN (Comprehensive Perl Archive Network) best practices.

  • Authoring Tools: Tools like Dist::Zilla (dzil), Minilla (minil), or App::ModuleBuild::Tiny streamline the creation of distribution skeletons, Makefile.PL or Build.PL files, testing setups, and metadata files (META.json/META.yml).
    • Example with Minilla: $ minil new My::Module creates a new distribution structure.
    • Example with Dist::Zilla: $ dzil new My::Module creates a distribution managed by Dist::Zilla plugins.
  • These tools typically generate a standard directory structure:
  • Files like MANIFEST (list of all files in the distribution) are often auto-generated.

CPAN is the central repository for Perl modules. The easiest way to install modules from CPAN is using a CPAN client.

  • cpanm (App::cpanminus): This is a popular, fast, and dependency-aware CPAN client. It’s often the recommended way to install modules.
    • To install cpanm itself (usually once): $ curl -L https://cpanmin.us | perl - App::cpanminus (or via system package manager).
    • To install a module: $ cpanm Module::Name
    • Example: $ cpanm DateTime
  • Traditional CPAN Shell: Perl comes with a cpan utility.
    • Start it: $ cpan
    • Install a module: cpan> install Module::Name
  • If you have a downloaded module distribution (e.g., My-Module-0.01.tar.gz):
    1. Extract it: $ tar -xzf My-Module-0.01.tar.gz
    1. Change directory: $ cd My-Module-0.01/
    1. If it has Makefile.PL (uses ExtUtils::MakeMaker):
  • `$ perl Makefile.PL`
  • `$ make`
  • `$ make test` (optional, but recommended)
  • `$ make install` (may require root/administrator privileges)
    1. If it has Build.PL (uses Module::Build or similar):
  • `$ perl Build.PL`
  • `$ ./Build`
  • `$ ./Build test` (optional, but recommended)
  • `$ ./Build install` (may require root/administrator privileges)

Perl searches for modules in a list of directories stored in the global array @INC. You can see these directories by running perl -V or perl -e 'print "$_\n" for @INC;'.