File Coverage

blib/lib/Data/MultiValued/TagContainer.pm
Criterion Covered Total %
statement 44 44 100.0
branch 15 16 93.7
condition n/a
subroutine 10 10 100.0
pod 3 3 100.0
total 72 73 98.6


line stmt bran cond sub pod time code
1             package Data::MultiValued::TagContainer;
2             {
3             $Data::MultiValued::TagContainer::VERSION = '0.0.1_4';
4             }
5             {
6             $Data::MultiValued::TagContainer::DIST = 'Data-MultiValued';
7             }
8 8     8   3554 use Moose;
  8         41  
  8         70  
9 8     8   64877 use namespace::autoclean;
  8         24  
  8         95  
10 8     8   680 use Moose::Util::TypeConstraints;
  8         20  
  8         122  
11 8     8   20061 use MooseX::Types::Moose qw(HashRef);
  8         22  
  8         113  
12 8     8   52573 use Data::MultiValued::Exceptions;
  8         36  
  8         5089  
13              
14             # ABSTRACT: container for tagged values
15              
16              
17             has _storage => (
18             is => 'rw',
19             isa => HashRef,
20             init_arg => undef,
21             default => sub { { } },
22             traits => ['Hash'],
23             handles => {
24             _has_tag => 'exists',
25             _get_tag => 'get',
26             _create_tag => 'set',
27             _delete_tag => 'delete',
28             all_tags => 'keys',
29             },
30             );
31              
32             has _default_tag => (
33             is => 'rw',
34             init_arg => undef,
35             predicate => '_has_default_tag',
36             clearer => '_clear_default_tag',
37             );
38              
39              
40             sub get {
41 105     105 1 276 my ($self,$args) = @_;
42              
43 105         323 my $tag = $args->{tag};
44              
45 105 100       363 if (!defined($tag)) {
46 68 100       4382 if ($self->_has_default_tag) {
47 63         3058 return $self->_default_tag;
48             }
49              
50             Data::MultiValued::Exceptions::TagNotFound->throw({
51 5         84 value => $tag,
52             });
53             }
54              
55 37 100       2200 if (!$self->_has_tag($tag)) {
56 8         121 Data::MultiValued::Exceptions::TagNotFound->throw({
57             value => $tag,
58             });
59             }
60 29         1795 return $self->_get_tag($tag);
61             }
62              
63              
64             sub get_or_create {
65 32     32 1 78 my ($self,$args) = @_;
66              
67 32         87 my $tag = $args->{tag};
68              
69 32 100       126 if (!defined($tag)) {
70 20 100       1293 if ($self->_has_default_tag) {
71 8         415 return $self->_default_tag;
72             }
73             else {
74 12         75 return $self->_default_tag(
75             $self->_create_new_inferior
76             );
77             }
78             }
79              
80 12 100       738 if (!$self->_has_tag($tag)) {
81 10         57 $self->_create_tag($tag,$self->_create_new_inferior);
82             }
83 12         710 return $self->_get_tag($tag);
84             }
85              
86             sub _clear_storage {
87 5     5   12 my ($self) = @_;
88              
89 5         248 $self->_storage({});
90             }
91              
92              
93             sub clear {
94 7     7 1 22 my ($self,$args) = @_;
95              
96 7         19 my $tag = $args->{tag};
97              
98 7 100       133 if (!defined($tag)) {
    50          
99 5         278 $self->_clear_default_tag;
100 5         39 $self->_clear_storage;
101             }
102             elsif ($self->_has_tag($tag)) {
103 2         109 $self->_delete_tag($tag);
104             }
105 7         42 return;
106             }
107              
108              
109             sub _create_new_inferior {
110 11     11   21 my ($self) = @_;
111 11         563 return {};
112             }
113              
114             __PACKAGE__->meta->make_immutable();
115              
116             1;
117              
118             __END__
119             =pod
120              
121             =encoding utf-8
122              
123             =head1 NAME
124              
125             Data::MultiValued::TagContainer - container for tagged values
126              
127             =head1 VERSION
128              
129             version 0.0.1_4
130              
131             =head1 DESCRIPTION
132              
133             Please don't use this module directly, use L<Data::MultiValued::Tags>.
134              
135             This module implements the storage for tagged data. It's almost
136             exactly a hash, the main difference being that C<undef> is a valid key
137             and it's distinct from the empty string.
138              
139             Another difference is that you get an exception if you try to access a
140             tag that's not there.
141              
142             Data is kept in "storage cells", as created by
143             L</_create_new_inferior> (by default, a hashref).
144              
145             =head1 METHODS
146              
147             =head2 C<get>
148              
149             my $value = $obj->get({ tag => $the_tag });
150              
151             Retrieves the "storage cell" for the given tag. Throws a
152             L<Data::MultiValued::Exceptions::TagNotFound|Data::MultiValued::Exceptions/Data::MultiValued::Exceptions::TagNotFound>
153             exception if the tag does not exists in this object.
154              
155             Not passing in a C<tag> is equivalent to passing in C<< tag => undef
156             >>.
157              
158             =head2 C<get_or_create>
159              
160             $obj->get_or_create({ tag => $the_tag });
161              
162             Retrieves the "storage cell" for the given tag. If the tag does not
163             exist, creates a new cell (see L</_create_new_inferior>), sets it for
164             the tag, and returns it.
165              
166             Not passing in a C<tag> is equivalent to passing in C<< tag => undef
167             >>.
168              
169             =head2 C<clear>
170              
171             $obj->clear({ tag => $the_tag });
172              
173             Deletes the given tag and all data associated with it. Does not throw
174             exceptions: if the tag does not exist, nothing happens.
175              
176             Not passing in a C<tag>, or passing C<< tag => undef >>, clears
177             everything. If you want to only clear the C<undef> tag, you may call
178             C<_clear_default_tag> (which is considered a "protected" method).
179              
180             =head2 C<all_tags>
181              
182             my @tags = $obj->all_tags;
183              
184             Returns all the tags defined in this object. Does not return the
185             C<undef> tag.
186              
187             =head2 C<_create_new_inferior>
188              
189             Returns a new "storage cell", by default an empty hashref. See
190             L<Data::MultiValued::TagContainerForRanges> for an example of use.
191              
192             =head1 AUTHOR
193              
194             Gianni Ceccarelli <dakkar@thenautilus.net>
195              
196             =head1 COPYRIGHT AND LICENSE
197              
198             This software is copyright (c) 2011 by Net-a-Porter.com.
199              
200             This is free software; you can redistribute it and/or modify it under
201             the same terms as the Perl 5 programming language system itself.
202              
203             =cut
204