ZetCode

Perl OOP

last modified October 8, 2026

In this article we show how to write object-oriented code in Perl. Perl has no special class syntax in its core; objects are ordinary references that have been marked with bless, and classes are packages.

This tutorial builds on the earlier articles about subroutines, hashes, and references. An object is usually a hash reference, and its methods are subroutines that receive the object as their first argument.

Creating objects with bless

The bless function marks a reference with a class name. It takes two arguments: the reference and the name of the class (package). The function returns the blessed reference. In the first example, we create a class with a constructor named new.

main.pl
#!/usr/bin/perl

use v5.34.0;
use warnings;

package Person;

sub new {
    my ($class, %args) = @_;

    my $self = {
        name => $args{name},
        age  => $args{age},
    };

    return bless $self, $class;
}

package main;

my $p = Person->new(name => 'Jane', age => 22);

say ref $p;
say "Name: $p->{name}";
say "Age: $p->{age}";

The Person package is a class. The new subroutine is a constructor. It receives the class name as its first argument, creates an anonymous hash, and blesses it into that class.

my ($class, %args) = @_;

When we call Person->new(...), Perl passes the string Person as the first argument. We store it in $class and read the named arguments from the rest of the list.

return bless $self, $class;

The hash reference is blessed into $class. Using the class name argument, instead of hard-coding 'Person', lets a subclass inherit the constructor and create objects of its own class.

$ ./main.pl
Person
Name: Jane
Age: 22

The ref function returns the class name of a blessed reference.

Accessors and mutators

An accessor reads an attribute; a mutator changes it. In the second example, each attribute has one subroutine that does both. If an argument is passed, it is stored; otherwise the current value is returned.

main.pl
#!/usr/bin/perl

use v5.34.0;
use warnings;

package Person;

sub new {
    my ($class, %args) = @_;
    my $self = { name => $args{name}, age => $args{age} };
    return bless $self, $class;
}

sub name {
    my $self = shift;
    $self->{name} = shift if @_;
    return $self->{name};
}

sub age {
    my ($self, $age) = @_;
    $self->{age} = $age if defined $age;
    return $self->{age};
}

package main;

my $p = Person->new(name => 'Jane', age => 22);
say "Name: ", $p->name;
say "Age: ", $p->age;

$p->age(23);
say "New age: ", $p->age;

$p->name('Janet');
say "New name: ", $p->name;

Method calls use the arrow operator, ->. Perl passes the invocant (the object) as the first argument, followed by any other arguments.

my $self = shift;
$self->{name} = shift if @_;
return $self->{name};

This is the invocant shift pattern. shift removes the object from @_ and stores it in $self. The remaining elements of @_ are the method's arguments. We check @_ to decide whether the call is a mutator (a value was given) or an accessor.

my ($self, $age) = @_;

The age method unpacks all its arguments at once. Both styles are common; the important point is that the first argument is always the object.

$ ./main.pl
Name: Jane
Age: 22
New age: 23
New name: Janet

Method chaining

If a mutator returns $self, calls can be chained. The next example uses a counter class in which each method returns the object.

main.pl
#!/usr/bin/perl

use v5.34.0;
use warnings;

package Counter;

sub new {
    my $class = shift;
    return bless { count => 0 }, $class;
}

sub increment {
    my $self = shift;
    $self->{count}++;
    return $self;
}

sub reset {
    my $self = shift;
    $self->{count} = 0;
    return $self;
}

sub value {
    my $self = shift;
    return $self->{count};
}

package main;

my $c = Counter->new;
say "Value: ", $c->increment->increment->increment->value;
say "After reset: ", $c->reset->increment->value;

Each increment call returns the same object, so the next method call applies to it. Perl evaluates the chain from left to right.

$ ./main.pl
Value: 3
After reset: 1

Class methods and object methods

A class method is called on the class name and receives the string as its first argument. An object method is called on a blessed reference. In the next example, total is a class method that reports how many objects have been created. Package-level lexical variables such as $instances are shared by all objects of the class.

main.pl
#!/usr/bin/perl

use v5.34.0;
use warnings;

package Counter;

my $instances = 0;

sub new {
    my $class = shift;
    $instances++;
    return bless { id => $instances }, $class;
}

sub total {
    my $class = shift;
    return $instances;
}

sub id {
    my $self = shift;
    return $self->{id};
}

package main;

say "Total before: ", Counter->total;

my $a1 = Counter->new;
my $a2 = Counter->new;

say "Total: ", Counter->total;
say "Object id: ", $a2->id;
say "Via object: ", $a1->total;

Calling total on an object also works, because the object is blessed into the class. Its first argument is then the object instead of the class name, which the method ignores here.

$ ./main.pl
Total before: 0
Total: 2
Object id: 2
Via object: 2

Inheritance with use parent

A subclass inherits methods from its parent class. The modern way to declare this is use parent -norequire, which sets up the inheritance through @ISA. The -norequire flag tells Perl not to load a module file, because both classes are defined in the same script. The older form, our @ISA = ('Animal');, does the same job.

main.pl
#!/usr/bin/perl

use v5.34.0;
use warnings;

package Animal;

sub new {
    my ($class, %args) = @_;
    my $self = { name => $args{name} };
    return bless $self, $class;
}

sub name {
    my $self = shift;
    return $self->{name};
}

sub speak {
    my $self = shift;
    return $self->name . " makes a sound";
}

package Dog;
use parent -norequire, 'Animal';

sub fetch {
    my $self = shift;
    return $self->name . " fetches the ball";
}

package main;

my $d = Dog->new(name => 'Rex');
say $d->speak;
say $d->fetch;
say "Dog isa Animal: ", ($d->isa('Animal') ? "yes" : "no");

Dog does not define new, name, or speak, but it inherits them from Animal. Method lookup starts in the object's class and then follows @ISA to the parent classes. The isa method, which every object inherits from UNIVERSAL, checks the inheritance chain.

$ ./main.pl
Rex makes a sound
Rex fetches the ball
Dog isa Animal: yes

Overriding methods with SUPER::

A subclass can replace a parent's method with its own version. To call the parent's version from inside the override, use SUPER::. The lookup for SUPER:: starts in the parent classes of the package where the method is defined.

main.pl
#!/usr/bin/perl

use v5.34.0;
use warnings;

package Animal;

sub new {
    my ($class, %args) = @_;
    return bless { name => $args{name} }, $class;
}

sub speak {
    my $self = shift;
    return $self->{name} . " makes a sound";
}

package Dog;
use parent -norequire, 'Animal';

sub speak {
    my $self = shift;
    my $base = $self->SUPER::speak();
    return "$base: Woof!";
}

package main;

my $d = Dog->new(name => 'Rex');
say $d->speak;

The Dog::speak method calls Animal::speak through SUPER:: and then extends its result. Without SUPER::, the call would recurse into Dog::speak itself.

$ ./main.pl
Rex makes a sound: Woof!

ref and blessed

The ref function returns the class name for a blessed reference, and the type (such as HASH) for an unblessed one. It returns an empty string for a non-reference. The blessed function from the core Scalar::Util module returns the class name, or undef if the value is not blessed. Use it when you need to tell objects apart from plain data structures.

main.pl
#!/usr/bin/perl

use v5.34.0;
use warnings;
use Scalar::Util qw(blessed);

package Shape;

sub new {
    my $class = shift;
    return bless {}, $class;
}

package Square;
use parent -norequire, 'Shape';

package main;

my $s = Square->new;
my $h = { x => 1 };

say "ref(\$s): ", ref($s);
say "ref(\$h): ", ref($h);
say "ref(\\1): ", ref(\1);
say "blessed(\$s): ", blessed($s);
say "blessed(\$h): ", (defined blessed($h) ? blessed($h) : 'undef');
say "\$s isa Shape: ", ($s->isa('Shape') ? 1 : 0);

For the blessed hash $s, ref gives the class name Square. For the plain hash $h, ref gives HASH, and blessed returns undef. A subclass object is also an instance of its parent, so isa is true for Shape.

Inside a method, ref($self) returns the class of the object that was actually called. This matters for methods that create new objects, such as a copy method, because it keeps subclass objects in their own class.

$ ./main.pl
ref($s): Square
ref($h): HASH
ref(\1): SCALAR
blessed($s): Square
blessed($h): undef
$s isa Shape: 1

Destructors

When the last reference to an object goes away, Perl calls its DESTROY method, if one exists. It is useful for cleanup such as closing handles. Perl uses reference counting, so the timing is predictable for simple cases like the one below.

main.pl
#!/usr/bin/perl

use v5.34.0;
use warnings;

package FileHandler;

sub new {
    my ($class, $name) = @_;
    say "Opening $name";
    return bless { name => $name }, $class;
}

sub DESTROY {
    my $self = shift;
    say "Closing $self->{name}";
}

package main;

{
    my $f = FileHandler->new('data.txt');
    say "Working with file";
}

say "Block finished";

The object is created inside a block. When the block ends, the variable $f goes out of scope, the reference count drops to zero, and DESTROY runs before the next statement.

$ ./main.pl
Opening data.txt
Working with file
Closing data.txt
Block finished

Moose and Moo

The examples above use only core Perl. Writing accessors, constructors, and argument checks by hand becomes repetitive in larger projects. For that reason, many programmers use object systems from CPAN instead. Moose is a full-featured object system that generates constructors and accessors for you. Moo is a lighter-weight alternative that covers most of the same needs with less overhead. Both are third-party modules and must be installed separately. Understanding plain bless-based objects is still useful, because these modules build on the same ideas.

In this article we have shown how to create classes and objects with bless, write constructors and accessors, call methods with ->, and build inheritance with use parent and SUPER::.

Author

My name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than ten years of experience in teaching programming.

List all Perl tutorials.