tags:

views:

156

answers:

3

What's the best practice for implementing Singletons in Perl?

+9  A: 

You can use the Class::Singleton module from CPAN.

For a simple class that's not supposed to be inherited, you can implement singleton using a private variable via my():

package My::Singleton;

{
    my $singleton;

    sub instance { # always returns the same instance
        unless (defined $singleton) {
            my $class = shift;
            my $self = { .. }; # create a new object     
            $singleton = bless $self, $class;
        }
        return $singleton;
    }
}
eugene y
This fails if the module is subclassed; the instance variable needs to live in the final package. Class::Singleton gets this right.
Michael Carman
@Michael Carman: thanks. I've updated my answer.
eugene y
It doesn't really "fail" if it's inherited. The inherited class just has to access and interact with the singleton object like any other class. However, that all depends on what you are trying to do.
brian d foy
+9  A: 

If you're using Moose, then MooseX::Singleton. Its interface is compatible with Class::Singleton.

daxim
+1  A: 

Singleton Summary:

  • Most of the time a normal object will work.
  • Be careful with singletons.
  • Localize interaction as much as possible

While singletons are a nice idea, I tend to just implement a normal object and use it. If it is critical that I only have one such object, I'll modify the constructor to throw a fatal exception when the second object is created. The various singleton modules don't seem to do much besides add a dependency.

I do this because it is easy, it works, and when in some weird future I need to work with a second object in my app, the changes are minimized.

I also like to localize interaction with my 'singleton' objects--keep interaction in as few places as possible. So instead of every object having direct access to the singleton, I mediate all interaction through my "Application" object. Whenever possible, the application object gets data from the 'singleton', and passes it as a parameter to the method in the other objects. Responses from other objects may also be munged and passed to the 'singleton'. All this effort helps when I need to make changes in the 'singleton' object, and when I want to reuse other objects in another app that may not need or be able to use the original 'singleton' object.

daotoad
I think you're missing the point of the singleton. It's a pattern you can use so you don't have to do all the complicated mediation. You don't have to use it, but don't discount it simply because you don't need it. Not everything fits in the scheme you've described.
brian d foy