File Coverage

blib/lib/Class/WeakSingleton.pm
Criterion Covered Total %
statement 25 25 100.0
branch 2 2 100.0
condition n/a
subroutine 7 7 100.0
pod 1 1 100.0
total 35 35 100.0


line stmt bran cond sub pod time code
1             package Class::WeakSingleton;
2              
3 2     2   31395 use 5.006;
  2         6  
  2         74  
4 2     2   11 use strict;
  2         3  
  2         64  
5 2     2   17 use warnings;
  2         3  
  2         213  
6              
7             =head1 NAME
8              
9             Class::WeakSingleton - A Singleton that expires when all the references to it expire
10              
11             =cut
12              
13             our $VERSION = '1.05';
14              
15             =head1 DESCRIPTION
16              
17             This is the Class::WeakSingleton module. A Singleton describes an
18             object class that can have only one instance in any system. An example
19             of a Singleton might be a print spooler, system registry or database
20             connection. A "weak" Singleton is not immortal and expires when all
21             other references to the original instance have expired. This module
22             implements a Singleton class from which other classes can be derived,
23             just like L. By itself, the Class::WeakSingleton
24             module does very little other than manage the instantiation of a
25             single object. In deriving a class from Class::WeakSingleton, your
26             module will inherit the Singleton instantiation method and can
27             implement whatever specific functionality is required.
28              
29             For a description and discussion of the Singleton class, see
30             L and "Design Patterns", Gamma et al,
31             Addison-Wesley, 1995, ISBN 0-201-63361-2.
32              
33             =head1 SYNOPSIS
34              
35             use Class::WeakSingleton;
36            
37             {
38             my $c = Class::WeakSingleton->instance;
39             my $d = Class::WeakSingleton->instance;
40             die "Mismatch" if $c != $d;
41             } # Class::WeakSingleton->instance expires
42             {
43             my $e = Class::WeakSingleton->instance;
44             {
45             my $f = Class::WeakSingleton->instance;
46             die "Mismatch" if $e != $f;
47             }
48             } # Class::WeakSingleton->instance expires
49              
50             =head1 OVERRIDABLE CLASS METHODS
51              
52             =over
53              
54             =item $singleton = YourClass->instance(...)
55              
56             Module constructor. Creates an Class::WeakSingleton (or derivative)
57             instance if one doesn't already exist. A weak reference is stored in
58             the C<$_instance> variable of the parent package. This means that
59             classes derived from Class::WeakSingleton will have the variables
60             defined in *THEIR* package, rather than the Class::WeakSingleton
61             package. Also, because the stored reference is weak it will be deleted
62             when all other references to the returned object have been
63             deleted. The first time the instance is created, the C<<
64             YourClass->_new_instance(...) >> constructor is called which simply
65             returns a reference to a blessed hash. This can be overloaded for
66             custom constructors. Any additional parameters passed to C<<
67             YourClass->instance(...) >> are forwarded to C<<
68             YourClass->_new_instance(...) >>.
69              
70             Returns a normal reference to the existing, or a newly created
71             Class::WeakSingleton object. If the C<< ->_new_instance(...) >> method
72             returns an undefined value then the constructer is deemed to have
73             failed.
74              
75             =cut
76              
77 2     2   10 use Scalar::Util 'weaken';
  2         3  
  2         261  
78              
79             sub instance {
80              
81             # instance()
82              
83 17     17 1 2504 my $class = shift;
84              
85             # get a reference to the _instance variable in the $class package
86 17         20 my $instance = do {
87             ## no critic
88 2     2   8 no strict 'refs';
  2         4  
  2         376  
89 17         18 \${ $class . "::_instance" };
  17         55  
90             };
91              
92 17 100       54 return $$instance if defined $$instance;
93              
94 8         33 my $new_instance = $$instance = $class->_new_instance(@_);
95              
96 8         53 weaken $$instance;
97              
98 8         22 return $new_instance;
99             }
100              
101             =item $singleton = YourClass->_new_instance(...)
102              
103             Simple constructor which returns a hash reference blessed into the
104             current class. May be overloaded to create non-hash objects or handle
105             any specific initialisation required.
106              
107             Returns a reference to the blessed hash.
108              
109             =cut
110              
111             sub _new_instance {
112 6     6   10 my $class = shift;
113              
114 6         17 return bless {}, $class;
115             }
116              
117             =back
118              
119             =head1 USING THE Class::WeakSingleton MODULE
120              
121             To import and use the Class::WeakSingleton module the following line
122             should appear in your Perl script:
123              
124             use Class::WeakSingleton;
125              
126             The C<< Class::WeakSingleton->instance(...) >> method is used to
127             create a new Class::WeakSingleton instance, or return a reference to
128             an existing instance. Using this method, it is only possible to have a
129             single instance of the class in any system at any given time. The
130             instance expires when all references to it also expire.
131              
132             {
133             my $highlander = Class::WeakSingleton->instance();
134              
135             Assuming that no Class::WeakSingleton object currently exists, this
136             first call to C<< Class::WeakSingleton->instance(...) >> will create a
137             new Class::WeakSingleton object and return a reference to it. Future
138             invocations of C<< Class::WeakSingleton->instance(...) >> will return
139             the same reference.
140              
141             my $macleod = Class::WeakSingleton->instance();
142             }
143              
144             In the above example, both C<$highlander> and C<$macleod> contain the
145             same reference to a Class::WeakSingleton instance. There can be only
146             one. Except that now that both C<$highlander> and C<$macleod> went
147             out of scope the singleton did also. So MacLeod is now dead. Boo hoo.
148              
149             =head1 DERIVING Class::WeakSingleton CLASSES
150              
151             A module class may be derived from Class::WeakSingleton and will
152             inherit the C<< ->instance(...) >> method that correctly instantiates
153             only one object.
154              
155             package Database;
156             use base 'Class::WeakSingleton';
157              
158             # derived class specific code
159             sub user_name { shift()->{user_name} }
160             sub login {
161             my $self = shift;
162             my ($user_name, $user_pass) = @_;
163              
164             return unless $user_name eq 'JJORE'
165             and $user_pass eq 'sekret';
166              
167             $self->{user_name} = $user_name;
168              
169             return 1;
170             }
171              
172             The Database class defined above could be used as follows:
173              
174             use Database;
175              
176             do_somestuff();
177             do_somestuff();
178              
179             sub do_somestuff {
180             my $db = Database->instance();
181              
182             $db->login(...);
183             }
184              
185             The C<< Database->instance() >> method calls the C<<
186             Database->_new_instance() >> constructor method the first and only
187             time a new instance is created (until the instance expires and then it
188             starts over). All parameters passed to the C<< Database->instance() >>
189             method are forwarded to C<< Database->_new_instance() >>. In the base
190             class this method returns a blessed reference to an empty hash array.
191             Derived classes may redefine it to provide specific object
192             initialisation or change the underlying object type (to a array
193             reference, for example).
194              
195             package MyApp::Database;
196             use base 'Class::WeakSingleton';
197             use DBI;
198              
199             # Object is an array ref, here are the names for the values
200             use constant DB => 0;
201              
202             our $ERROR = '';
203              
204             # this only gets called the first time instance() is called
205             sub _new_instance {
206             my $class = shift;
207             my $self = bless [], $class;
208             my $db = shift || "myappdb";
209             my $host = shift || "localhost";
210              
211             $self->[ DB ] = DBI->connect("DBI:mSQL:$db:$host")
212             if ( not defined $self->[DB] ) {
213             $ERROR = "Cannot connect to database: $DBI::errstr\n";
214             return undef;
215             }
216              
217             # any other initialisation...
218              
219             # return sucess
220             return $self;
221             }
222              
223             Some time later on in a module far, far away...
224              
225             package MyApp::FooBar
226             use MyApp::Database;
227              
228             sub new {
229             # usual stuff...
230              
231             # this FooBar object needs access to the database; the Singleton
232             # approach gives a nice wrapper around global variables.
233              
234             # new instance is returned
235             my $database = MyApp::Database->instance();
236              
237             # more stuff...
238             # call some methods
239             }
240              
241             sub some_methods {
242             # more usual stuff
243              
244             # Get the same object that was used in new()
245             my $database = MyApp::Database->instance;
246             }
247              
248             The Class::WeakSingleton instance() method uses a package variable to
249             store a reference to any existing instance of the object. This
250             variable, <$_instance>, is coerced into the derived class package
251             rather than the base class package.
252              
253             Thus, in the MyApp::Database example above, the instance variable
254             would be C<$MyApp::Database::_instance>.
255              
256             This allows different classes to be derived from Class::WeakSingleton
257             that can co-exist in the same system, while still allowing only one
258             instance of any one class to exists. For example, it would be
259             possible to derive both 'Database' and 'MyApp::Database' from
260             Class::WeakSingleton and have a single instance of each.
261              
262             =head1 AUTHOR
263              
264             Joshua ben Jore
265              
266             Thanks to Andy Wardley for writing Class::Singleton.
267              
268             =head1 COPYRIGHT
269              
270             Copyright (C) 2006 Joshua ben Jore. All Rights Reserved.
271              
272             This module is free software; you can redistribute it and/or modify it
273             under the term of the Perl Artistic License.
274              
275             =head1 SEE ALSO
276              
277             =over
278              
279             =item L
280              
281             =item Design Patterns
282              
283             Class::WeakSingleton is an implementation of the Singleton class described in
284             "Design Patterns", Gamma et al, Addison-Wesley, 1995, ISBN 0-201-63361-2
285              
286             =back
287              
288             =cut
289