Class-StrongSingleton
view release on metacpan or search on metacpan
lib/Class/StrongSingleton.pm view on Meta::CPAN
package Class::StrongSingleton;
use strict;
use warnings;
our $VERSION = '0.02';
my %instances;
my %constructors;
## protected initializer
sub _init_StrongSingleton {
# do not let us be called by anything which
# is not derived from Class::StrongSingleton
(UNIVERSAL::isa((caller)[0], 'Class::StrongSingleton'))
|| die "Illegal Operation : _init_StrongSingleton can only be called by a subclass of Class::StrongSingleton";
my ($self) = @_;
(ref($self))
|| die "Illegal Operation : _init_StrongSingleton can only be called as an instance method";
# get the class name
my $class = ref($self);
(!exists($instances{$class}))
|| die "Illegal Operation : cannot call _init_StrongSingleton with a valid Singleton instance";
# assuming new was the name of our
# constructor, otherwise ...
my $constructor = $self->can("new");
(defined($constructor))
|| die "Illegal Operation : Singleton objects must have a 'new' method";
# store the constructor for later
$constructors{$class} = $constructor;
# put the instance in the instances table
$instances{$class} = $self;
no strict 'refs';
no warnings 'redefine';
# then override the new method to return the
# single instance.
*{"${class}::new"} = sub { return $_[0]->instance() };
}
# for backwards compatability we retain the old _init
*_init = \&_init_StrongSingleton;
### destructor
sub DESTROY {
my ($self) = @_;
# get the class name
my $class = ref($self) || $self;
# if there is no valid singleton, then
# we can just return
return unless exists($instances{$class});
# otherwise ...
no strict 'refs';
no warnings 'redefine';
# return the contructor to its original state
*{"${class}::new"} = $constructors{$class};
# delete completely the unique instance
delete $instances{$class};
# at this point all should be back to normal
}
### methods
sub instance {
my $self = shift;
# get the class name or
# if it is being called from
# the class, then use that string
my $class = ref($self) || $self;
# return single instance of self, assuming there is one
return $instances{$class} if exists $instances{$class};
# otherwise we call new for you
return $class->new(@_);
}
1;
( run in 0.312 second using v1.01-cache-2.11-cpan-5511b514fd6 )