in reply to Module vs Singleton

Singletons are easier than you might suppose to do in Perl ... but first, you’re going to have to “un-learn” some of your C++.

Perl objects live in packages.   Yet, there is nothing special about them, except that they contain a subroutine which by convention is named new, and which contains something along the order of the following:

my $class = shift;
my $self = {};
bless $self, $class;
return $self;

Now, what this code is doing is to instantiate a hashref and then to bless it, which tells Perl that this hash (it could be some other kind of data-structure) is to behave like an object.   Then, the subroutine returns that hashref.   Since the hashref is being returned, it isn’t going out of scope so it isn’t destroyed by the garbage-collector.

So, how would you create a singleton?   Through the use of a package variable.   Like this:

my $singleton = undef; sub new { my $class = shift; unless (defined($singleton)) { $singleton = {}; bless $singleton, $class; } return $singleton; }

Now, only the first call to new will initiate a new object.   Every successive call will simply return the same one.

When you are coming from a highly-strictured language like C++, working with Perl can sometimes feel like barnstorming.   “Now that’s flying...!”

Replies are listed 'Best First'.
Re^2: Module vs Singleton
by Anonymous Monk on Jul 16, 2011 at 04:12 UTC
    What you have explained here clears my understanding.

    Actually, I had searched around and found Class::Singleton and had followed the documentation in that to work with the singleton objects. I was deriving from Class::Singleton. What you have explained is perhaps a simpler way of doing it without requiring the inheritance.

    Also, it had never occurred to me that I could use modules for some of these instead of Singletons.

    For example, if I had a set of utility functions, I created a Singleton class for it where a module perhaps would have been more appropriate.

    It works. But perhaps it is not the right way and less efficient. Should I go back to clean this up and convert some of the Singletons to modules?

      There's nothing wrong with singletons. This would be a good time to explore Moose, especially MooseX::Singleton. Following up on Anonymous Monk's "new", here's what I tried:
      package Foo; use MooseX::Singleton; has stuff => ( is => 'rw', isa => 'HashRef[Str]', default => sub { { default => 'new' } }, ); package main; my $instance = Foo->instance; my $same = Foo->instance; use Data::Dumper::Concise; print Dumper($same);

      Oh, no, no ... if you have found a CPAN module to do what you are looking for, I am always in favor of going that route, because doing so usually gives you a more-robust and well-thought-out solution with less work.   Those CPAN contributors are gooood ...

      Nevermind any concerns for the computer’s “efficiency.”   (At however-many billion operations per second, no one can hear you scream ...)   Rather, think only about your own.   What is the easiest and most reliable to build ... the most serviceable and maintainable ... the most obvious, both now and six months from now when your own code has become the work of a perfect stranger.   (How soon we forget, especially as we get old... aww, forget it...)   ;-)   If you have already put your hand to the plow, it’s rarely a good idea to look back.

      You will soon hear around here this familiar mantra:   TMTOWTDI.™   (a.k.a. “Tim Toady.”)   And you will soon know why we say it.

        I do appreciate the knowledge shared here. I have much reading to do. I will keep in mind the advice received.

        Thank you.