File Coverage

blib/lib/Class/StrongSingleton.pm
Criterion Covered Total %
statement 40 40 100.0
branch 12 12 100.0
condition 4 6 66.6
subroutine 10 10 100.0
pod 1 1 100.0
total 67 69 97.1


line stmt bran cond sub pod time code
1              
2             package Class::StrongSingleton;
3              
4 1     1   42720 use strict;
  1         4  
  1         37  
5 1     1   6 use warnings;
  1         1  
  1         173  
6              
7             our $VERSION = '0.02';
8              
9             my %instances;
10             my %constructors;
11            
12             ## protected initializer
13             sub _init_StrongSingleton {
14             # do not let us be called by anything which
15             # is not derived from Class::StrongSingleton
16 8 100   8   4683 (UNIVERSAL::isa((caller)[0], 'Class::StrongSingleton'))
17             || die "Illegal Operation : _init_StrongSingleton can only be called by a subclass of Class::StrongSingleton";
18 7         15 my ($self) = @_;
19 7 100       27 (ref($self))
20             || die "Illegal Operation : _init_StrongSingleton can only be called as an instance method";
21             # get the class name
22 6         10 my $class = ref($self);
23 6 100       23 (!exists($instances{$class}))
24             || die "Illegal Operation : cannot call _init_StrongSingleton with a valid Singleton instance";
25             # assuming new was the name of our
26             # constructor, otherwise ...
27 5         36 my $constructor = $self->can("new");
28 5 100       23 (defined($constructor))
29             || die "Illegal Operation : Singleton objects must have a 'new' method";
30             # store the constructor for later
31 4         7 $constructors{$class} = $constructor;
32             # put the instance in the instances table
33 4         7 $instances{$class} = $self;
34 1     1   6 no strict 'refs';
  1         6  
  1         33  
35 1     1   6 no warnings 'redefine';
  1         2  
  1         150  
36             # then override the new method to return the
37             # single instance.
38 4     6   15 *{"${class}::new"} = sub { return $_[0]->instance() };
  4         29  
  6         1959  
39             }
40              
41             # for backwards compatability we retain the old _init
42             *_init = \&_init_StrongSingleton;
43              
44             ### destructor
45             sub DESTROY {
46 5     5   1087 my ($self) = @_;
47             # get the class name
48 5   66     22 my $class = ref($self) || $self;
49             # if there is no valid singleton, then
50             # we can just return
51 5 100       124 return unless exists($instances{$class});
52             # otherwise ...
53 1     1   5 no strict 'refs';
  1         2  
  1         39  
54 1     1   109 no warnings 'redefine';
  1         2  
  1         202  
55             # return the contructor to its original state
56 2         4 *{"${class}::new"} = $constructors{$class};
  2         19  
57             # delete completely the unique instance
58 2         11 delete $instances{$class};
59             # at this point all should be back to normal
60             }
61              
62             ### methods
63              
64             sub instance {
65 12     12 1 518 my $self = shift;
66             # get the class name or
67             # if it is being called from
68             # the class, then use that string
69 12   66     49 my $class = ref($self) || $self;
70             # return single instance of self, assuming there is one
71 12 100       79 return $instances{$class} if exists $instances{$class};
72             # otherwise we call new for you
73 1         5 return $class->new(@_);
74             }
75              
76             1;
77              
78             __END__