Perl Packages & Modules
Perl - Packages & Modules
Section titled “Perl - Packages & Modules”Packages and modules are fundamental to Perl’s design, enabling code organization, reusability, and namespacing.
What are Packages?
Section titled “What are Packages?”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
packagedeclaration switches the current compilation context to the specified namespace. This effect lasts until anotherpackagestatement 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 perluse strict;use warnings;
# This is the 'main' package by defaultour $i = 1; # Package variableprint "In package: ", __PACKAGE__, ", \$i = $i\n";
package Foo;# Now we are in the 'Foo' packageour $i = 10; # A different $i, scoped to Fooprint "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' packageour $i = 20;print "In package: ", __PACKAGE__, ", \$i = $i\n";Foo::bar(); # Calling a sub from another package
package main;# Switching back to the 'main' packageour $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 valueWhen the above code is executed, it produces:
In package: main, $i = 1In package: Foo, $i = 10In package: Bar, $i = 20Function bar in package Foo reporting: FooIn package: main, $i = 100Accessing Foo's $i from main: 10Accessing Bar's $i from main: 20BEGIN and END Blocks
Section titled “BEGIN and END Blocks”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.}BEGINblocks are executed immediately after they are fully compiled, even before the rest of the file is parsed. MultipleBEGINblocks execute in the order they appear.ENDblocks are executed in reverse order of their appearance, just before the interpreter exits. They run even if the script exits due to an uncaughtdie.- These blocks are particularly useful in modules for setup (
BEGIN) or cleanup (END) tasks.
Example of BEGIN and END blocks:
#!/usr/bin/env perluse 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!What are Perl Modules?
Section titled “What are Perl Modules?”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:
package MyUtils;use strict;use warnings;
# This module will export 'greet' by defaultrequire Exporter;our @ISA = qw(Exporter);our @EXPORT = qw(greet);
# This function can be exportedsub greet { my ($name) = @_; print "Hello, $name!\n";}
# This function is not exported by defaultsub 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
useandrequirestatements are used to load modules. - Both
useandrequiresearch for module files in the directories listed in the@INCarray. use ModuleName;is equivalent toBEGIN { require ModuleName; ModuleName->import(); }. It loads the module at compile time and calls itsimportmethod (often inherited fromExporterto bring symbols into the caller’s namespace).require ModuleName;loads the module at runtime and does not callimportautomatically.- The
1;at the end of a module file ensures that its compilation (and loading viarequireoruse) evaluates to a true value, indicating success.
The require Function
Section titled “The require Function”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 perluse strict;use warnings;
# Assuming MyUtils.pm is in a directory in @INCrequire MyUtils;
MyUtils::greet("World"); # Must use full package name# MyUtils::internal_helper(); # This would also work if called explicitlyThe use Function
Section titled “The use Function”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 perluse strict;use warnings;
# Assuming MyUtils.pm is in a directory in @INCuse 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.pmpackage MyUtils;use strict;use warnings;
require Exporter;our @ISA = qw(Exporter); # Inherit from Exporterour @EXPORT = qw(greet); # Export 'greet' by defaultour @EXPORT_OK = qw(another_func); # Export 'another_func' on requestour %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 perluse 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), orApp::ModuleBuild::Tinystreamline the creation of distribution skeletons,Makefile.PLorBuild.PLfiles, testing setups, and metadata files (META.json/META.yml). -
- Example with
Minilla:$ minil new My::Modulecreates a new distribution structure.
- Example with
-
- Example with
Dist::Zilla:$ dzil new My::Modulecreates a distribution managed by Dist::Zilla plugins.
- Example with
- These tools typically generate a standard directory structure:
- Files like
MANIFEST(list of all files in the distribution) are often auto-generated.
Installing Perl Modules from CPAN
Section titled “Installing Perl Modules from CPAN”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
cpanmitself (usually once):$ curl -L https://cpanmin.us | perl - App::cpanminus(or via system package manager).
- To install
-
- To install a module:
$ cpanm Module::Name
- To install a module:
-
- Example:
$ cpanm DateTime
- Example:
- Traditional CPAN Shell: Perl comes with a
cpanutility. -
- Start it:
$ cpan
- Start it:
-
- Install a module:
cpan> install Module::Name
- Install a module:
- If you have a downloaded module distribution (e.g.,
My-Module-0.01.tar.gz): -
- Extract it:
$ tar -xzf My-Module-0.01.tar.gz
- Extract it:
-
- Change directory:
$ cd My-Module-0.01/
- Change directory:
-
- If it has
Makefile.PL(usesExtUtils::MakeMaker):
- If it has
-
`$ perl Makefile.PL`
-
`$ make`
-
`$ make test` (optional, but recommended)
-
`$ make install` (may require root/administrator privileges)
-
- If it has
Build.PL(usesModule::Buildor similar):
- If it has
-
`$ 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;'.