File Coverage

blib/lib/Data/Keys.pm
Criterion Covered Total %
statement 38 38 100.0
branch 5 8 62.5
condition n/a
subroutine 9 9 100.0
pod 2 2 100.0
total 54 57 94.7


line stmt bran cond sub pod time code
1             package Data::Keys;
2              
3             =head1 NAME
4              
5             Data::Keys - get/set key+value extensible manipulations, base module for Data::Keys::E::*
6              
7             =head1 SYNOPSIS
8              
9             use Date::Keys;
10             my $dk = Data::Keys->new(
11             'base_dir' => '/folder/full/of/json/files',
12             'extend_with' => ['Store::Dir', 'Value::InfDef'],
13             'inflate' => sub { JSON::Util->decode($_[0]) },
14             'deflate' => sub { JSON::Util->encode($_[0]) },
15             );
16              
17             my %data = %{$dk->get('abcd.json')};
18             $dk->set('abcd.json', \%data);
19              
20             =head1 WARNING
21              
22             experimental, use at your own risk :-)
23              
24             =head1 DESCRIPTION
25              
26             L<Data::Keys> is just a base class module that purpose is to allow loading
27             extensions in C<Data::Keys::E::*> namespace.
28              
29             =head1 EXTENSIONS
30              
31             =head2 storage
32              
33             L<Data::Keys::E::Store::Dir>, L<Data::Keys::E::Store::Mem>
34              
35             =cut
36              
37 13     13   1071054 use warnings;
  13         27  
  13         463  
38 12     12   54 use strict;
  12         19  
  12         420  
39              
40             our $VERSION = '0.04';
41              
42 12     12   7744 use Moose;
  12         4953043  
  12         93  
43 12     12   77718 use Moose::Util;
  12         26  
  12         145  
44 12     12   9793 use Carp::Clan 'confess';
  12         20035  
  12         90  
45 12     12   2511 use List::MoreUtils 'none';
  12         8867  
  12         125  
46              
47             =head1 PROPERTIES
48              
49             =head2 extend_with
50              
51             Array ref list of extensions to apply to the object.
52              
53             =cut
54              
55             has 'extend_with' => ( isa => 'ArrayRef', is => 'ro', lazy => 1, default => sub { [] });
56             has '_extend_arg' => ( isa => 'HashRef', is => 'ro');
57              
58             # store all attributes from extensions
59             around BUILDARGS => sub {
60             my $orig = shift;
61             my $class = shift;
62             my %args = @_;
63              
64             my $extend_with = $args{'extend_with'};
65             if ((defined $extend_with) and (not ref $extend_with)) {
66             $extend_with = [ $extend_with ];
67             $args{'extend_with'} = $extend_with;
68             }
69            
70             # load extension modules that are not loaded already
71             foreach my $extension (@{$extend_with}) {
72             my $package = 'Data::Keys::E::'.$extension;
73             my $package_file = $package.'.pm';
74             $package_file =~ s{::}{/}g;
75             if (not $INC{$package_file}) {
76 11     11   5830 eval 'use '.$package;
  10         30  
  10         231  
77             confess 'failed to load '.$package
78             if $@;
79             }
80             }
81            
82             my %e_attrs =
83             map { $_ => delete $args{$_} }
84             grep { defined $args{$_} }
85             map { $_->meta->get_attribute_list }
86             map { 'Data::Keys::E::'.$_ }
87             @{$extend_with}
88             ;
89             $args{_extend_arg} = \%e_attrs;
90            
91             my @attrs = Data::Keys->meta->get_attribute_list;
92             my @unknown_keys =
93             grep { my $attr = $_; none { $_ eq $attr } @attrs }
94             keys %args
95             ;
96             confess 'unknown attributes - '.join(', ', @unknown_keys)
97             if @unknown_keys;
98            
99             return $class->$orig(%args);
100             };
101              
102             =head2 BUILD
103              
104             Loads all extensions when L<Key::Values> object is created and calls
105             C<< $self->init(); >> which can be used to initialize an extension.
106              
107             =cut
108              
109             sub BUILD {
110 14     14 1 30 my $self = shift;
111            
112 14         515 my $extend_with = $self->extend_with;
113 14 50       74 if (defined $extend_with) {
114 14         29 foreach my $to_extend (@{$extend_with}) {
  14         56  
115 34         64568 $to_extend = 'Data::Keys::E::'.$to_extend;
116 34         204 $to_extend->meta->apply($self);
117             }
118             }
119            
120             # init all attributes from extensions
121 14         74879 my $extend_arg = $self->_extend_arg;
122 14         30 foreach my $name (keys %{$extend_arg}) {
  14         61  
123 13 50       150 confess 'extended attribute '.$name.' not found'
124             if not $self->can($name);
125 13         546 $self->$name(delete $extend_arg->{$name});
126             }
127            
128 14         114 $self->init();
129             }
130              
131             __PACKAGE__->meta->make_immutable;
132              
133             =head1 METHODS
134              
135             =head2 new()
136              
137             Object constructor.
138              
139             =head2 init()
140              
141             Called after the object is C<BUILD>.
142              
143             =cut
144              
145             sub init {
146 14     14 1 260 my $self = shift;
147            
148 14 100       100 confess 'role with set/get is mandatory'
149             if not $self->can('set');
150 13 50       78 confess 'role with set/get is mandatory'
151             if not $self->can('get');
152            
153 13         61 return;
154             }
155            
156             1;
157              
158              
159             __END__
160              
161             =head1 AUTHOR
162              
163             Jozef Kutej
164              
165             =cut
166              
167              
168             =head1 AUTHOR
169              
170             jozef@kutej.net, C<< <jkutej at cpan.org> >>
171              
172             =head1 BUGS
173              
174             Please report any bugs or feature requests to C<bug-data-keys at rt.cpan.org>, or through
175             the web interface at L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Data-Keys>. I will be notified, and then you'll
176             automatically be notified of progress on your bug as I make changes.
177              
178              
179              
180              
181             =head1 SUPPORT
182              
183             You can find documentation for this module with the perldoc command.
184              
185             perldoc Data::Keys
186              
187              
188             You can also look for information at:
189              
190             =over 4
191              
192             =item * RT: CPAN's request tracker
193              
194             L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=Data-Keys>
195              
196             =item * AnnoCPAN: Annotated CPAN documentation
197              
198             L<http://annocpan.org/dist/Data-Keys>
199              
200             =item * CPAN Ratings
201              
202             L<http://cpanratings.perl.org/d/Data-Keys>
203              
204             =item * Search CPAN
205              
206             L<http://search.cpan.org/dist/Data-Keys/>
207              
208             =back
209              
210              
211             =head1 ACKNOWLEDGEMENTS
212              
213              
214             =head1 LICENSE AND COPYRIGHT
215              
216             Copyright 2010 jozef@kutej.net.
217              
218             This program is free software; you can redistribute it and/or modify it
219             under the terms of either: the GNU General Public License as published
220             by the Free Software Foundation; or the Artistic License.
221              
222             See http://dev.perl.org/licenses/ for more information.
223              
224              
225             =cut
226              
227             1; # End of Data::Keys