File Coverage

lib/MooseX/Role/Registry.pm
Criterion Covered Total %
statement 7 9 77.7
branch n/a
condition n/a
subroutine 3 3 100.0
pod n/a
total 10 12 83.3


line stmt bran cond sub pod time code
1             package MooseX::Role::Registry;
2 1     1   481 use strict;
  1         2  
  1         34  
3 1     1   6 use warnings;
  1         2  
  1         69  
4              
5             our $VERSION = '1.00';
6              
7             =head1 NAME
8              
9             MooseX::Role::Registry
10              
11             =head1 VERSION
12              
13             1.00
14              
15             =head1 SYNOPSYS
16              
17             package Foo::Registry;
18             use Moose;
19             with 'MooseX::Role::Registry';
20              
21             sub config_file {
22             return '/foo_objects.yml';
23             }
24              
25             sub build_registry_object {
26             my $self = shift;
27             my $name = shift;
28             my $values = shift || {};
29              
30             return Foo->new({
31             name => $name,
32             %$values
33             });
34             }
35              
36             package main;
37             my $registry = Foo::Registry->instance;
38             my $foo = $registry->get('bar');
39              
40             =head1 DESCRIPTION
41              
42             This role watches a file which describes a hashref of objects in yml format.
43             This hashref is called a "registry" because the objects in the hashref can be
44             requested by name using I<get>.
45              
46             Implementations should be singletons! In other words, when using a class that is
47             derived from MooseX::Role::Registry, you shouldn't call I<new>. Instead,
48             just get the singelton object using the I<instance> method and call I<get> on
49             the result.
50              
51             =cut
52              
53 1     1   233 use Moose::Role;
  0            
  0            
54             use namespace::autoclean;
55             use Carp;
56             use Try::Tiny;
57             use YAML::XS qw(LoadFile);
58              
59             =head1 REQUIRED SUBCLASS METHODS
60              
61             =head2 config_filename
62              
63             Returns the filesystem path of the default location of the configuration file
64             that is watched by a given consumer of MooseX::Role::Registry
65              
66             =cut
67              
68             requires 'config_file';
69              
70             =head2 build_registry_object
71              
72             A function to create an object of the registy entry
73              
74             =cut
75              
76             requires 'build_registry_object';
77              
78             =head1 METHODS
79              
80             =head2 get($name)
81              
82             Returns the registered entity called $name, or undef if none exists.
83              
84             =cut
85              
86             sub get {
87             my $self = shift;
88             my $key = shift;
89              
90             return unless ($key);
91             return $self->_registry->{$key};
92             }
93              
94             =head2 all
95              
96             Returns all of the objects stored in the registry. Useful for generic grep() calls.
97              
98             =cut
99              
100             sub all {
101             my $self = shift;
102             return values %{ $self->_registry };
103             }
104              
105             =head2 keys
106              
107             Returns a list of all of the (lookup) keys of objects currently registered in $self.
108              
109             =cut
110              
111             sub keys ## no critic (ProhibitBuiltinHomonyms)
112             {
113             my $self = shift;
114             my @result = sort { $a cmp $b } ( keys %{ $self->_registry } );
115             return @result;
116             }
117              
118             =head2 registry_fixup
119              
120             A callback which allows subclasses to modify the hashref of loaded objects before
121             they are stored in memory as part of I<$self>.
122              
123             =cut
124              
125             sub registry_fixup {
126             my $self = shift;
127             my $registry = shift;
128             return
129             $registry; # Default implementation is to leave the loaded hashref alone
130             }
131              
132             has _registry => (
133             is => 'rw',
134             isa => 'HashRef',
135             lazy_build => 1
136             );
137              
138             has _db => (
139             is => 'rw',
140             isa => 'HashRef',
141             lazy_build => 1
142             );
143              
144             sub _build__db {
145             my $self = shift;
146              
147             return YAML::XS::LoadFile( $self->config_file );
148             }
149              
150             sub _build__registry {
151             my $self = shift;
152             my $registry = $self->_db;
153              
154             # If we've made it this far we no longer need this key
155             delete $registry->{version};
156              
157             foreach my $key ( CORE::keys %$registry ) {
158              
159             # TOTALLY coding to the coverage tool here. This sucks.
160             my $reg_defn = $registry->{$key};
161             my $reg_defn_type = ref $reg_defn;
162             if ( not $reg_defn_type or ( $reg_defn_type eq 'HASH' ) ) {
163             try {
164             $registry->{$key} =
165             $self->build_registry_object( $key, $reg_defn );
166             }
167             catch {
168             Carp::croak( "Unable to convert entry $key in "
169             . $self->config_file
170             . " into a registry entry : $_" );
171             };
172             }
173             else {
174             Carp::croak( "Invalid entry $key in "
175             . $self->config_file
176             . ", not a hash" );
177             }
178             }
179              
180             return $self->registry_fixup($registry);
181             }
182              
183             sub BUILD {
184             my $self = shift;
185             $self->_registry;
186             return;
187             }
188              
189             1;
190              
191             __END__
192              
193             =head1 DEPENDENCIES
194              
195             =over 4
196              
197             =item L<Moose::Role>
198              
199             =item L<namespace::autoclean>
200              
201             =item L<Try::Tiny>
202              
203             =item L<YAML::XS>
204              
205             =back
206              
207             =head1 SOURCE CODE
208              
209             L<GitHub|https://github.com/binary-com/perl-MooseX-Role-Registry>
210              
211             =head1 AUTHOR
212              
213             binary.com, C<< <perl at binary.com> >>
214              
215             =head1 BUGS
216              
217             Please report any bugs or feature requests to
218             C<bug-moosex-role-registry at rt.cpan.org>, or through the web
219             interface at
220             L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=MooseX-Role-Registry>.
221             We will be notified, and then you'll automatically be notified of progress on
222             your bug as we make changes.
223              
224             =head1 SUPPORT
225              
226             You can find documentation for this module with the perldoc command.
227              
228             perldoc MooseX::Role::Registry
229              
230             You can also look for information at:
231              
232             =over 4
233              
234             =item * RT: CPAN's request tracker (report bugs here)
235              
236             L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=MooseX-Role-Registry>
237              
238             =item * AnnoCPAN: Annotated CPAN documentation
239              
240             L<http://annocpan.org/dist/MooseX-Role-Registry>
241              
242             =item * CPAN Ratings
243              
244             L<http://cpanratings.perl.org/d/MooseX-Role-Registry>
245              
246             =item * Search CPAN
247              
248             L<http://search.cpan.org/dist/MooseX-Role-Registry/>
249              
250             =back
251              
252             =head1 LICENSE AND COPYRIGHT
253              
254             Copyright (C) 2015 binary.com
255              
256             This program is free software; you can redistribute it and/or modify it
257             under the terms of the the Artistic License (2.0). You may obtain a
258             copy of the full license at:
259              
260             L<http://www.perlfoundation.org/artistic_license_2_0>
261              
262             Any use, modification, and distribution of the Standard or Modified
263             Versions is governed by this Artistic License. By using, modifying or
264             distributing the Package, you accept this license. Do not use, modify,
265             or distribute the Package, if you do not accept this license.
266              
267             If your Modified Version has been derived from a Modified Version made
268             by someone other than you, you are nevertheless required to ensure that
269             your Modified Version complies with the requirements of this license.
270              
271             This license does not grant you the right to use any trademark, service
272             mark, tradename, or logo of the Copyright Holder.
273              
274             This license includes the non-exclusive, worldwide, free-of-charge
275             patent license to make, have made, use, offer to sell, sell, import and
276             otherwise transfer the Package with respect to any patent claims
277             licensable by the Copyright Holder that are necessarily infringed by the
278             Package. If you institute patent litigation (including a cross-claim or
279             counterclaim) against any party alleging that the Package constitutes
280             direct or contributory patent infringement, then this Artistic License
281             to you shall terminate on the date that such litigation is filed.
282              
283             Disclaimer of Warranty: THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER
284             AND CONTRIBUTORS "AS IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES.
285             THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
286             PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY
287             YOUR LOCAL LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR
288             CONTRIBUTOR WILL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR
289             CONSEQUENTIAL DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE,
290             EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
291              
292             =cut
293