File Coverage

blib/lib/Data/SingletonManager.pm
Criterion Covered Total %
statement 29 30 96.6
branch 6 10 60.0
condition 7 12 58.3
subroutine 8 8 100.0
pod 4 4 100.0
total 54 64 84.3


line stmt bran cond sub pod time code
1             =head1 NAME
2              
3             Data::SingletonManager - return/set/clear instances of singletons identified by keys in different namespaces.
4              
5             =head1 SYNOPSIS
6              
7             package My::Object;
8             sub instance {
9             my %args;
10             ...
11             my $key = "$args{userid}-$args{object_id}";
12             return Data::SingletonManager->instance(
13             namespace => __PACKAGE__, # default; may omit.
14             key => $key,
15             creator => sub {
16             return __PACKAGE__->new_instance($args{userid},
17             $args{object_id});
18             }
19             );
20             }
21              
22             package main;
23              
24             # return all singletons loaded in a namespace:
25             @loaded_objs = Data::SingletonManager->instances("My::Object");
26              
27             # clear all singletons, in all packages (perhaps on new web request)
28             Data::SingletonManager->clear_all;
29              
30             # clear all singletons in one namespace
31             Data::SingletonManager->clear("My::Object");
32              
33             =head1 DESCRIPTION
34              
35             This is a small utility class to help manage multiple keyed singletons
36             in multiple namespaces. It is not a base class so you can drop it into
37             any of your classes without namespace clashes with methods you might
38             already have, like "new", "instance", "new_instance", etc.
39              
40             =head1 PACKAGE METHODS
41              
42             All methods below are package methods. There are no instance methods.
43              
44             =over
45              
46             =cut
47              
48              
49             ############################################################################
50              
51             package Data::SingletonManager;
52 2     2   1714 use strict;
  2         4  
  2         85  
53 2     2   11 use Carp qw(croak);
  2         4  
  2         165  
54 2     2   11 use vars qw($VERSION);
  2         13  
  2         1121  
55             $VERSION = "1.00";
56              
57             my %data; # namespace -> key -> value
58              
59             =item instance(%args)
60              
61             Package method to return (or create and save) a keyed instance where %args are:
62              
63             =over
64              
65             =item "namespace"
66              
67             defaults to the calling package
68              
69             =item "key"
70              
71             scalar key for instance. the (namespace, key) uniquely identifies an instance
72              
73             =item "creator"
74              
75             subref to return the instance if it doesn't already exist
76              
77             =back
78              
79             =cut
80              
81             sub instance {
82 11     11 1 4096 my $class = shift;
83              
84 11         46 my %args = @_;
85              
86 11   66     47 my $ns = delete $args{namespace} || _calling_package();
87              
88 11 50       41 my $key = delete $args{key} or
89             croak "Argument 'key' required.";
90              
91 11 50       32 my $creator = delete $args{creator} or
92             croak "Argument 'creator' required.";
93            
94 11 50       26 croak "Unknown argument(s): " . join(", ", keys %args) if %args;
95              
96             # return instance if we have it, else set it
97 11   66     70 return $data{$ns}{$key} ||= $creator->();
98             }
99              
100             ############################################################################
101              
102             =item instances([ $namespace ])
103              
104             Return an array of all loaded instances in a namespace, which defaults
105             to the calling namespace if no namespace is given.
106              
107             =cut
108              
109             sub instances {
110 1     1 1 514 my $class = shift;
111 1   33     5 my $ns = shift || _calling_package();
112 1 50       4 return () unless $data{$ns};
113 1         3 return values %{ $data{$ns} };
  1         5  
114             }
115              
116             ############################################################################
117              
118             =item clear([ $namespace ])
119              
120             Clears all instances in a namespace, which defaults to the calling
121             namespace if no namespace is given.
122              
123             =cut
124              
125             sub clear {
126 4     4 1 1624 my $class = shift;
127 4   66     38 my $ns = shift || _calling_package();
128 4         16 delete $data{$ns};
129             }
130              
131             ############################################################################
132              
133             =item clear_all
134              
135             Clears all instances in all namespaces.
136              
137             =cut
138              
139             sub clear_all {
140 1     1 1 618 %data = ();
141             }
142              
143              
144             ############################################################################
145             # Utility methods
146             ############################################################################
147              
148             sub _calling_package {
149 10     10   15 my $i = 0;
150 10         66 while (my ($pkg) = caller($i++)) {
151 20 100       96 next if $pkg eq __PACKAGE__;
152 10         44 return $pkg;
153             }
154 0           die;
155             }
156              
157             ############################################################################
158              
159             =head1 AUTHORS
160              
161             Brad Fitzpatrick
162              
163             =head1 COPYRIGHT AND LICENSE
164              
165             Copyright 2005 by Six Apart, Ltd.
166              
167             License is granted to use and distribute this module under the same
168             terms as Perl itself.
169              
170             =cut
171              
172             1;