By convention, a Perl5 class's constructor is typically written to create a new object by blessing a new anonymous hash (or other reference). (Smalltalkers will note the similarity between
bless and a one-way
#become:) Objects created in this manner are distinct.
Arranging to create and return a singleton object is straightforward: bless an object when the constructor (e.g.
new) is first invoked, remember that object, and hand it out on subsequent invocations of the constructor.
[Singleton.pm]
package Singleton;
my $singleton;
sub new {
my $class = shift;
$singleton ||= bless {}, $class;
}
...
[foo.pl]
require Singleton;
my $object1 = new Singleton;
my $object2 = new Singleton; # same object!
--
DaveSmith
Yet another way (I won't claim this is better, but it avoids any extra logic on subsequent calls to new):
package Foo;
sub new {
*new = \&old;
$Foo::bar = bless {}, shift;
}
sub old {
$Foo::bar;
}
An alternative is to exploit the feature that perl classes are just namespaces (i.e. packages) with functions in them. Since every namespace is automatically unique in a perl program, it can be a singleton object itself. In this case, the "object" is the name of the class.
Like so:
my $sngl = 'Some::Singleton::Class';
$sngl->foo;
as long as that subroutine exists in that package, everything works fine.
There are, of course, ways to wrap this approach in an abstraction that makes it look like normal (blessed-ref) object usage.
[Perl punctuation commentary follows]
The ||= operator is a handy lazy assignment operator which evaluates the rhs and assigns it to the lhs if and only if the lhs evaluates as false.
(The only "problem" is that || tests for truth, not definedness. However, references are always true, so there is no problem in this case.)
So equivalent long-hand notations include:
$singleton = bless {}, $class unless $singleton;
$singleton or $singleton = bless {}, $class;
$singleton = $singleton ? $singleton : bless {}, $class;
Using these longer forms, you can test for definedness explicitly.
As always,
ThereIsMoreThanOneWayToDoIt... but consider that
||= gives the lowest
PerlGolf score ;-).
And since perl 5.9.0, you can use //= to test the definedness.
Contributors:
IlmariKaronen,
KirrilyRobert,
JohnDouglasPorter,
SlavenRezic
I do something like this now:
1.
ClassName::
ClassSingleton() for access to a single instance of the class.
2.
ClassName::Singleton(primary key) to get a cached version or create an object
and then cache it.
I find these idioms easy and obvious. Being too clever isn't a win.
I find that "new" is inappropriate in a singleton API. My view is that you
should not call a constructor, but instead a getInstance () method. That way,
it's lucid in your client code that indeed you're dealing with a singleton. It
will help you avoid hours of searching when you're wondering why several "new"
objects are not really new at all.
hubo
Compare with
PythonSingleton and
RubySingleton