Skip to content
CPAN and Modules
step 1/5

Reading — step 1 of 5

Learn

~2 min readReal-World Perl

CPAN (Comprehensive Perl Archive Network) is Perl's package repository — and the original of the species. NPM, PyPI, RubyGems all came after.

The ethos: 200,000+ modules. Battle-tested for decades. The Perl saying "there's a module for that" predates the App Store.

Installing modules:

cpanm Module::Name           # cpanminus — recommended
cpan Module::Name             # legacy interactive

In this Judge0 sandbox we can't install — but we can use what's already bundled with Perl 5.28's core:

Core modules worth knowing:

  • List::Util — sum, min, max, first, reduce, any, all, none, uniq
  • Scalar::Util — looks_like_number, blessed, weaken, dualvar
  • POSIX — strftime, floor, ceil, mathematical functions
  • File::Spec — portable path manipulation
  • File::Basename — dirname, basename
  • File::Find — recursive directory walk
  • Cwd — getcwd, abs_path
  • Time::Piece — DateTime-lite parsing/formatting
  • Data::Dumper — debugging dump
  • JSON::PP — pure-Perl JSON (no XS dependency)
  • Storable — binary serialization
  • Carp — better error reporting (croak, confess)
  • Getopt::Long — command-line parsing

Using List::Util:

use List::Util qw(sum max min first uniq);

my @nums = (3, 1, 4, 1, 5, 9, 2, 6);
print sum @nums;                  # 31
print max @nums;                  # 9
print first { $_ > 4 } @nums;     # 5
print join ",", uniq @nums;       # 3,1,4,5,9,2,6

Carp for better errors:

use Carp qw(croak carp confess);

sub validate {
    croak "invalid" unless defined $_[0];   # error from caller's perspective
}

croak reports from the caller's line — much more useful than die in library code. confess includes a full stack trace.

JSON::PP:

use JSON::PP;

my $data = { name => "Ada", age => 36 };
my $json = encode_json($data);     # '{"name":"Ada","age":36}'
my $back = decode_json($json);

Time::Piece:

use Time::Piece;
my $now = localtime;
print $now->ymd;                   # 2026-05-08
print $now->strftime("%Y-%m-%d %H:%M:%S");

my $parsed = Time::Piece->strptime("2026-01-01", "%Y-%m-%d");
print $parsed->day_of_week;

Defining your own module — file MyLib.pm:

package MyLib;
use strict;
use warnings;

use Exporter 'import';
our @EXPORT_OK = qw(foo bar);

sub foo { ... }
sub bar { ... }

1;

Consumer:

use MyLib qw(foo bar);
foo();

Exporter: @EXPORT (auto-imported), @EXPORT_OK (opt-in), %EXPORT_TAGS (groups). Convention: prefer @EXPORT_OK so users explicitly opt in.

Versioning:

our $VERSION = '1.04';

Users can use MyLib 1.0; to require min version.

Practical CPAN modules to know exist:

  • Mojolicious — web framework + non-blocking HTTP client + WebSocket
  • Dancer2 — Sinatra-style web framework
  • DBI + DBD::* — database interface (DB-agnostic)
  • Moose / Moo — modern OOP
  • Try::Tiny — try/catch
  • Path::Tiny — modern path object
  • HTTP::Tiny — pure-Perl HTTP client (core)
  • LWP::UserAgent — full-featured HTTP client
  • XML::LibXML — XML
  • Text::CSV — CSV parsing
  • Test::More — testing

Perl's CPAN is its enduring superpower. For text processing, sysadmin scripts, glue code — there's almost certainly a battle-tested module.

Discussion

Ask a question, share an insight, or help someone who’s stuck.

Sign in to post a comment or reply.

Loading…