Modules & CPAN
📦 Modules & CPAN
cpanm. This chapter covers the full picture: loading existing modules properly, writing and exporting your own, and CPAN itself — one of the oldest, largest package ecosystems in programming, predating both npm and PyPI's modern form by well over a decade.
📥 use vs. require
use is what you want for essentially all real code — it loads the module and imports its exported symbols at compile time, before the rest of the script even runs. require loads at runtime instead, with no automatic import — genuinely useful for the rarer case of conditionally loading a module based on logic that can't be known until the script is actually running.
✍️ Writing Your Own Module
This reuses Chapter 3's package declaration directly — a module is just a package, conventionally saved in a file matching its name (Utils.pm for package Utils;).
When use or require loads a file, Perl checks the file's last evaluated expression — if it isn't true, loading fails with Utils.pm did not return a true value. The trailing 1; is a plain true value placed deliberately as the file's final statement, purely to satisfy this requirement. Forgetting it is a genuinely common first-module mistake — the module's actual code can be entirely correct and still fail to load.
📤 Exporting Symbols with Exporter
@EXPORT_OK lists symbols available for opt-in import — the calling script must explicitly request them (use Utils qw(shout);). This is the recommended practice over the older @EXPORT, which exports everything listed unconditionally into every script that uses the module — a real risk of silently colliding with the caller's own subroutine or variable names. Explicit opt-in keeps namespace pollution under the caller's control.
🌐 The CPAN Ecosystem
CPAN (the Comprehensive Perl Archive Network) launched in 1995 — genuinely one of the oldest centralized package repositories in programming, predating npm (2010) and PyPI's modern form by well over a decade. It's a significant part of why Perl became so practically useful early: an enormous, searchable library of community-published modules for nearly anything.
A cpanfile declares a project's dependencies — the direct Perl parallel to Course 1, Chapter 9's Python requirements.txt or Node's package.json.
⭐ A Few Genuinely Useful CPAN Modules
| Module | What it's for |
|---|---|
Path::Tiny | The nicer file-handling wrapper previewed back in Course 1, Chapter 8 — read/write a whole file in one call |
JSON::PP | JSON encoding/decoding — actually part of Perl core since 5.14, no install needed |
Try::Tiny | A cleaner error-handling syntax, previewed ahead of Chapter 6 |
DateTime | Robust date/time handling, well beyond localtime's context-sensitive quirkiness from Chapter 2 |
🔧 A Worked Example — A Small Module
CPAN vs. pip/npm
The underlying model is the same across all three — a central registry, a simple install command, community-published packages. The real difference is age and culture: CPAN's 1995 launch makes it genuinely older than npm or PyPI's current form by well over a decade, and it fostered a "there's already a well-tested module for this" culture in Perl development early — much of the reason Perl earned a reputation as a practical, get-things-done language for real work, not just an academic one.
use vs require
Compile-time with automatic import, vs. runtime with none.
The trailing 1;
Every .pm file must end with a true value or loading fails.
@EXPORT_OK
Opt-in exporting — safer than unconditional @EXPORT.
cpanm / cpanfile
The modern CPAN client, and a project's declared dependencies.
💻 Coding Challenges
Challenge 1: Write and Use a Module
Write a module StringUtils.pm exporting a subroutine reverse_string via @EXPORT_OK. Write a separate script that uses it and prints the result of reversing "Perl".
Challenge 2: Diagnose the Missing 1;
Given a module file whose last line is a subroutine definition (with no trailing 1;), explain in one sentence what error occurs when a script tries to use it, and show the corrected final lines.
Challenge 3: use vs require
Write two versions of loading and calling List::Util's max function on the list (3, 9, 4) — one using use with a qw() import list, one using require with a fully-qualified call — and explain in one sentence the key difference between them.
🎯 What's Next
Next chapter: Error Handling — die/eval, $@, and modern try/catch (Perl 5.34+).