How can I implement a singleton class in perl?
Asked Answered
O

4

9

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

Osteitis answered 22/2, 2010 at 10:47 Comment(4)
The best practice for implementing singletons is Don't!Showpiece
@gbacon - what would be the reason(s) against implementing sigletons? Granted I've never used them extensively (or rather almost never) but I'm not aware of any reason to avoid them as opposed to just not necessarily needing them.Mendel
@Mendel A singleton is a global variable wearing a fancy suit.Showpiece
@gbacon, if you have a central object (singleton or not) that is either passed around everywhere, or stored as an attribute of your other objects, you have the same exposure to spooky action bugs. Using a singleton means that you don't have to worry about accidentally creating two distinct versions of the object. Any time you have a widely shared object or data structure, you have to be very careful. Despite the problems, sometimes it is best to use such an object. Examples of sane things to use a singleton for are intra-application message passing, configuration and open handle management.Long
W
18

You can use the Class::Singleton module.

A "Singleton" class can also be easily implemented using either my or state variable (the latter is available since Perl 5.10). But see the @Michael's comment below.

package MySingletonClass;
use strict;
use warnings;
use feature 'state';

sub new {
    my ($class) = @_;
    state $instance;

    if (! defined $instance) {
        $instance = bless {}, $class;
    }
    return $instance;
}
Windstorm answered 22/2, 2010 at 10:52 Comment(2)
This fails if the module is subclassed; the instance variable needs to live in the final package. Class::Singleton gets this right.Favour
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.Tartaric
E
9

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

Equivocal answered 22/2, 2010 at 12:33 Comment(0)
L
3

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.

Long answered 22/2, 2010 at 16:53 Comment(1)
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.Tartaric
P
0

Here an example of a singleton class.

package MySingletonClass;
use strict;
use warnings;
# Do no use use feature 'state'; before perl 5.17
my $instance; # = null ; 
sub new {
    my ($class) = @_;
    
    if (! defined $instance) {
        $instance = bless {}, $class;
    }
    return $instance;
}
Pepi answered 22/11, 2023 at 11:2 Comment(2)
How is this better than the accepted answer?Osteitis
@Osteitis Because it does not use advanced features of perl and can run on RHEL5.Pepi

© 2022 - 2024 — McMap. All rights reserved.