Object-Oriented Perl (Classic)
🏛️ Object-Oriented Perl (Classic)
class keyword here: a "class" is just a package combined with a blessed reference, built entirely out of tools already covered — packages, references (Course 1, Chapter 9), and subroutines (Course 1, Chapter 7).
📦 Packages — Perl's Namespace Mechanism
package Animal; declares a namespace — every subroutine defined after it, until the next package statement (or end of file), belongs to Animal. In real code, one package typically lives in its own .pm file named to match (Animal.pm), loaded elsewhere with use Animal; (Chapter 5 covers modules in depth).
🎯 bless — Turning a Reference into an Object
bless takes an ordinary reference (a hashref, almost always) and a class name, and marks that reference as an instance of that class — nothing more mysterious than that. new is not a language keyword — it's just a subroutine name, chosen entirely by convention. Nothing stops you naming a constructor something else, but every real Perl codebase calls it new, and deviating would only confuse readers.
📞 Methods — Just Subroutines with an Implicit First Argument
$animal->speak() is really just syntax sugar for speak($animal) — Course 1, Chapter 7's @_-based argument passing, unchanged. The object arrives as the very first element of @_, which is why my $self = shift; is the near-universal first line of every method — exactly the same shift from Course 1, Chapter 3's array operations, now doing double duty as "unpack the invocant."
🧬 @ISA — Manual Inheritance
@ISA ("is a") is a package variable listing a package's parent(s). When a method is called, Perl searches the current package first, then walks @ISA looking for a match — Dog defining its own speak means that version wins, but Dog still inherits Animal's new automatically, since Dog never defines its own.
Directly assigning @ISA works, but use parent -norequire, 'Animal'; is the more common modern form — it does the same thing, with slightly better error-checking behavior. Both are worth recognizing; @ISA itself is what's actually happening underneath either spelling.
⬆️ Calling the Parent's Method — SUPER::
SUPER::method() explicitly calls the parent class's version of a method rather than the current package's — useful for extending, rather than fully replacing, inherited behavior.
🔧 A Worked Example — Animal/Dog/Cat Hierarchy
The foreach loop never checks "is this a Dog or a Cat" — calling ->speak() automatically runs whichever version belongs to that object's actual class. This is the identical polymorphism concept from the site's own Python course (py2-2's Dog/Cat example) — same idea entirely, expressed through completely different mechanics: Python's built-in class system versus Perl's manual package-plus-bless construction.
A constructor's first argument is always the class name — Dog->new("Rex") passes @_ = ('Dog', 'Rex'), not just ('Rex'). Forgetting my $class = shift; as the very first line, before unpacking anything else, means every later argument is off by one — a classic, confusing bug where the constructor silently receives the wrong values with no error at all.
Classic Perl OOP vs. Python Classes
Python's class keyword, automatic self parameter, and __init__ constructor are all built directly into the language. Classic Perl OOP has none of that: self (called $self here) is an ordinary variable you manually shift off @_ yourself, new is a plain subroutine name rather than a reserved constructor keyword, and "class" simply means "package plus bless." Nothing is hidden or automatic — which is precisely why Chapter 4's Moo/Moose covers a considerably more ergonomic modern alternative, while this chapter's manual version remains essential for reading the vast amount of existing Perl code still built this way.
package
Declares a namespace — the closest thing classic Perl has to a "class."
bless
Marks an ordinary reference as belonging to a class.
Methods
$obj->method() is sugar for method($obj) — always shift first.
@ISA / SUPER::
Manual inheritance; SUPER:: explicitly calls the parent's version.
💻 Coding Challenges
Challenge 1: A Basic Class
Write a package Book with a new($title) constructor and a describe method returning "Title: $title". Create an instance and call describe on it.
Challenge 2: Inheritance with @ISA
Write a package Shape with an area method returning 0, then a subclass Square (using @ISA) with its own constructor storing a side and its own area method computing side * side.
Challenge 3: Extend with SUPER::
Given the chapter's Animal/Dog classes, write a LoudDog subclass (inheriting from Dog) whose own speak calls SUPER::speak and appends " (LOUDLY)" to the result.
🎯 What's Next
Next chapter: Modern OOP with Moo/Moose — a lighter, more ergonomic alternative to hand-rolled OOP, with attributes and roles.