Packages and Modules

23.1 Packages and Namespaces

package Counter;          # switches the current namespace
our $count = 0;
sub increment { $count++ }

package main;             # back to the default namespace
Counter::increment();
say $Counter::count;      # fully qualified name

package My::Block {       # block syntax (5.14+)
    sub hello { 'hi' }
}

23.2 Writing a Module

# lib/My/Math.pm
package My::Math;
use v5.36;
use Exporter 'import';                     # provides the import method

our $VERSION   = '1.00';
our @EXPORT_OK = qw(add multiply PI);      # exported on request
our %EXPORT_TAGS = (all => \@EXPORT_OK);
# our @EXPORT = qw(add);                   # exported by default (avoid: namespace pollution)

use constant PI => 3.14159;

sub add($x, $y)      { $x + $y }
sub multiply($x, $y) { $x * $y }
sub _private_helper  { ... }               # underscore = private by convention

1;                                         # a module must return a true value (not required since 5.38 with use v5.37+)
__END__

=head1 NAME

My::Math - Simple math utilities
# script.pl
use v5.36;
use FindBin qw($Bin);
use lib "$Bin/lib";                        # add the local lib directory to @INC
use My::Math qw(add PI);
use My::Math ':all';
say add(2, 3), ' ', PI;
say My::Math::multiply(2, 3);              # fully qualified (no import needed)
say My::Math->VERSION;

23.3 use vs require

use Module LIST; require Module; Compile time (BEGIN { require Module; Module->import(LIST) }) Optional/conditional loading

if (eval { require JSON::XS; 1 }) { say 'Using JSON::XS' } else { require JSON::PP }
use Module ();                     # load without importing anything
use Module 2.0;                    # require a minimum version
use if $^O eq 'MSWin32', 'Win32::Console';   # conditional use
use Module::Runtime qw(use_module);           # load by name at runtime
my $class = use_module("My::Plugin::$name");

23.4 @INC and %INC

. was removed from @INC in 5.26 for security. Use use lib or FindBin.

perl -E 'say for @INC'             # module search path
perl -MList::Util -E 'say $INC{"List/Util.pm"}'   # where a loaded module came from
PERL5LIB=/path/to/lib perl script.pl

23.5 Core Modules Worth Knowing

strict, warnings, utf8, feature, autodie List::Util, Scalar::Util, Hash::Util Data::Dumper, Storable Debug dumping, serialization/deep copy

File::Spec, File::Basename, File::Path, File::Copy, File::Find, File::Temp, Cwd Getopt::Long, Pod::Usage

Time::Local, Time::HiRes, Time::Piece, POSIX Time and system

Encode, Unicode::Normalize, Unicode::Collate JSON::PP, HTTP::Tiny, IO::Socket::IP JSON, HTTP client, sockets

Test::More, Test2::V0 (Test2::Suite is core in recent Perls; check with corelist Test2::V0)

Carp, Try::Tiny (CPAN), constant, parent, base Errors, inheritance Benchmark, Devel::Peek Performance, internals IPC::Open3, IPC::Cmd

Digest::MD5, Digest::SHA, MIME::Base64 threads, threads::shared, Thread::Queue

corelist Module (from Module::CoreList) tells you which Perl version first included a module.