Implementing the singleton pattern in Perl

Wednesday, 11 December by David Farrell

The Singleton is a well-known object oriented design pattern that allows only one object of a class to be created. It's often cited as the most popular design pattern from the original "gang of four" book. But when should you use it in Perl and how?

When to use it

The Singleton is such a popular pattern it is sometimes called an anti-pattern as the legitimate cases to use it are relatively rare. Consider using the Singleton when one of the following needs arises:

  • You have a single resource that needs to be reused across several different parts of a system. A logger is a good example of this (Log::log4perl implements the Singleton pattern).
  • You need to ensure only one instance exists as the class cannot perform correctly if there is more than one instance of it (e.g. a file system, a game loop).
  • You need a singleton as a component of another design pattern (Abstract Factory, Builder, Prototype)
If you do not have one of the above needs, you may not need to use the Singleton pattern. Using Singletons encourages the coupling of code, which can make unit testing, sub-classing and debugging harder.

Implementation of a Singleton Class

Instead of implementing a "new" constructor, the Singleton class implements an "get_instance" method which will return a new object if it doesn't already exist, else it returns the existing instance. The Singleton class is shown below:

package Singleton;

my $instance = undef;

sub get_instance {
    $instance = bless {}, shift unless $instance;
    return $instance;
}

1;

To test the Singleton get_instance method we can run the following script:

use strict;
use warnings;
use Singleton; 

my $singleton_1 = Singleton->get_instance;
$singleton_1->{favourite_animal} = 'llama'; # of course!

my $singleton_2 = Singleton->get_instance;

print $singleton_2->{favourite_animal} . "\n";

This script constructs a new object using "get_instance" and assigns it to a variable called "$singleton_1". It adds an attribute to the object ("favourite_animal"). The script then calls the "get_instance" method again and assigns the resulting object to a new variable called "$singleton_2". Printing the "favourite_animal" key-value attribute of the object returns the same value that was set using "$singleton_1", proving that we have one underlying instance and both variables ("$singleton_1" and "$singleton_2") point to it.

Further reading