File Coverage

blib/lib/Data/Pairs.pm
Criterion Covered Total %
statement 181 181 100.0
branch 81 94 86.1
condition 11 12 91.6
subroutine 27 27 100.0
pod 13 15 86.6
total 313 329 95.1


line stmt bran cond sub pod time code
1             #---------------------------------------------------------------------
2             package Data::Pairs;
3             #---------------------------------------------------------------------
4              
5             =head1 NAME
6              
7             Data::Pairs - Perl module to implement ordered mappings with possibly
8             duplicate keys.
9              
10             =head1 SYNOPSIS
11              
12             use Data::Pairs;
13            
14             # Simple OO style
15            
16             my $pairs = Data::Pairs->new( [{a=>1},{b=>2},{c=>3},{b=>4}] );
17            
18             $pairs->set( a => 0 );
19             $pairs->add( b2 => 2.5, 2 ); # insert at position 2 (between b and c)
20            
21             my($value) = $pairs->get_values( 'c' ); # 3 (if you just want one)
22             my @values = $pairs->get_values( 'b' ); # (2, 4) (one key, multiple values)
23             my @keys = $pairs->get_keys(); # (a, b, b2, c, b)
24             @values = $pairs->get_values(); # (0, 2, 2.5, 3, 4)
25             my @subset = $pairs->get_values(qw(c b)); # (2, 3, 4) (values are data-ordered)
26            
27             # Tied style
28              
29             # Alas, because of duplicate keys, tying to a %hash is not supported.
30            
31             # Non-OO style
32              
33             use Data::Pairs ':ALL';
34            
35             my $pairs = [{a=>1},{b=>2},{c=>3},{b=>4}]; # new-ish, but not blessed
36              
37             pairs_set( $pairs, a => 0 ); # (pass pairs as first parameter)
38             pairs_add( $pairs, b2 => 2.5, 2 ); # insert at position 2 (between b and c)
39            
40             my($value) = pairs_get_values( $pairs, 'c' ); # 3 (if you just want one)
41             my @values = pairs_get_values( $pairs, 'b' ); # (2, 4) (one key, multiple values)
42             my @keys = pairs_get_keys( $pairs ); # (a, b, b2, c, b)
43             @values = pairs_get_values( $pairs ); # (0, 2, 2.5, 3, 4)
44             my @subset = pairs_get_values( $pairs, qw(c b) ); # (2, 3, 4) (values are data-ordered)
45            
46             # There are more methods/options, see below.
47              
48             =head1 DESCRIPTION
49              
50             This module implements the Data::Pairs class. Objects in this class
51             are ordered mappings, i.e., they are hashes in which the key/value
52             pairs are in order. This is defined in shorthand as C in the
53             YAML tag repository: http://yaml.org/type/pairs.html.
54              
55             The keys in Data::Pairs objects are not necessarily unique, unlike
56             regular hashes.
57              
58             A closely related class, Data::Omap, implements the YAML C
59             data type, http://yaml.org/type/omap.html. Data::Omap objects are
60             also ordered sequences of key/value pairs but they do not allow
61             duplicate keys.
62              
63             While ordered mappings are in order, they are not necessarily in a
64             I order, i.e., they are not necessarily sorted in any
65             way. They simply have a predictable set order (unlike regular hashes
66             whose key/value pairs are in no set order).
67              
68             By default, Data::Pairs will add new key/value pairs at the end of the
69             mapping, but you may request that they be merged in a particular
70             order with the C class method.
71              
72             However, even though Data::Pairs will honor the requested order, it
73             will not attempt to I the mapping in that order. By passing
74             position values to the C and C methods, you may insert
75             new pairs anywhere in the mapping and Data::Pairs will not complain.
76              
77             =head1 IMPLEMENTATION
78              
79             Normally, the underlying structure of an OO object is encapsulated
80             and not directly accessible (when you play nice). One key
81             implementation detail of Data::Pairs is the desire that the underlying
82             ordered mapping data structure (an array of single-key hashes) be
83             publically maintained as such and directly accessible if desired.
84              
85             To that end, no attributes but the data itself are stored in the
86             objects. In the current version, that is why C is a class
87             method rather than an object method. In the future, inside-out
88             techniques may be used to enable object-level ordering.
89              
90             This data structure is inefficient in several ways as compared to
91             regular hashes: rather than one hash, it contains a separate hash per
92             key/value pair; because it's an array, key lookups (in the current
93             version) have to loop through it.
94              
95             The advantage if using this structure is simply that it "natively"
96             matches the structure defined in YAML. So if the (unblessed)
97             structure is dumped using YAML (or perhaps JSON), it may be read as
98             is by another program, perhaps in another language. It is true that
99             this could be accomplished by passing the object through a formatting
100             routine, but I wanted to see first how this implementation might work.
101              
102             =head1 VERSION
103              
104             Data::Pairs version 0.07
105              
106             =cut
107              
108 6     6   301243 use 5.008003;
  6         24  
  6         245  
109 6     6   37 use strict;
  6         11  
  6         263  
110 6     6   32 use warnings;
  6         16  
  6         265  
111              
112             our $VERSION = '0.07';
113              
114 6     6   33 use Scalar::Util qw( reftype looks_like_number );
  6         9  
  6         953  
115 6     6   34 use Carp;
  6         11  
  6         339  
116 6     6   43 use Exporter qw( import );
  6         24  
  6         15242  
117             our @EXPORT_OK = qw(
118             pairs_set pairs_get_values pairs_get_keys
119             pairs_exists pairs_delete pairs_clear
120             pairs_add pairs_order pairs_get_pos
121             pairs_get_pos_hash pairs_get_array
122             pairs_is_valid pairs_errstr
123             );
124             our %EXPORT_TAGS = (
125             STD => [qw(
126             pairs_set pairs_get_values pairs_get_keys
127             pairs_exists pairs_delete pairs_clear )],
128             ALL => [qw(
129             pairs_set pairs_get_values pairs_get_keys
130             pairs_exists pairs_delete pairs_clear
131             pairs_add pairs_order pairs_get_pos
132             pairs_get_pos_hash pairs_get_array
133             pairs_is_valid pairs_errstr )],
134             );
135              
136             my $order; # package global, see order() accessor
137             our $errstr; # error message
138              
139             #---------------------------------------------------------------------
140              
141             =head1 CLASS METHODS
142              
143             =head2 Data::Pairs->new();
144              
145             Constructs a new Data::Pairs object.
146              
147             Accepts array ref containing single-key hash refs, e.g.,
148              
149             my $pairs = Data::Pairs->new( [ { a => 1 }, { b => 2 }, { c => 3 }, { b => 4 } ] );
150              
151             When provided, this data will be loaded into the object.
152              
153             Returns a reference to the Data::Pairs object.
154              
155             =cut
156              
157             sub new {
158 19     19 1 6593 my( $class, $aref ) = @_;
159 19 100       58 return bless [], $class unless $aref;
160              
161 18 100       37 croak pairs_errstr() unless pairs_is_valid( $aref );
162 12         46 bless $aref, $class;
163             }
164              
165             sub pairs_is_valid {
166 18     18 0 24 my( $aref ) = @_;
167 18 100 66     205 unless( $aref and ref( $aref ) and reftype( $aref ) eq 'ARRAY' ) {
      100        
168 2         4 $errstr = "Invalid pairs: Not an array reference";
169 2         9 return;
170             }
171 16         30 for my $href ( @$aref ) {
172 48 100       98 unless( ref( $href ) eq 'HASH' ) {
173 3         4 $errstr = "Invalid pairs: Not a hash reference";
174 3         11 return;
175             }
176 45         90 my @keys = keys %$href;
177 45 100       121 if( @keys > 1 ) {
178 1         3 $errstr = "Invalid pairs: Not a single-key hash";
179 1         4 return;
180             }
181             }
182 12         37 return 1; # is valid
183             }
184              
185             sub pairs_errstr {
186 6     6 0 7 my $msg = $errstr;
187 6         6 $errstr = "";
188 6         653 $msg; # returned
189             }
190              
191             #---------------------------------------------------------------------
192              
193             =head2 Data::Pairs->order( [$predefined_ordering | coderef] );
194              
195             When ordering is ON, new key/value pairs will be added in the
196             specified order. When ordering is OFF (the default), new pairs
197             will be added to the end of the mapping.
198              
199             When called with no parameters, C returns the current code
200             reference (if ordering is ON) or a false value (if ordering is OFF);
201             it does not change the ordering.
202              
203             Data::Pairs->order(); # leaves ordering as is
204              
205             When called with the null string, C<''>, ordering is turned OFF.
206              
207             Data::Pairs->order( '' ); # turn ordering OFF (the default)
208              
209             Otherwise, accepts the predefined orderings: 'na', 'nd', 'sa', 'sd',
210             'sna', and 'snd', or a custom code reference, e.g.
211              
212             Data::Pairs->order( 'na' ); # numeric ascending
213             Data::Pairs->order( 'nd' ); # numeric descending
214             Data::Pairs->order( 'sa' ); # string ascending
215             Data::Pairs->order( 'sd' ); # string descending
216             Data::Pairs->order( 'sna' ); # string/numeric ascending
217             Data::Pairs->order( 'snd' ); # string/numeric descending
218             Data::Pairs->order( sub{ int($_[0]/100) < int($_[1]/100) } ); # code
219              
220             The predefined orderings, 'na' and 'nd', compare keys as numbers.
221             The orderings, 'sa' and 'sd', compare keys as strings. The
222             orderings, 'sna' and 'snd', compare keys as numbers when they are
223             both numbers, as strings otherwise.
224              
225             When defining a custom ordering, the convention is to use the
226             operators C<< < >> or C between (functions of) C<$_[0]> and
227             C<$_[1]> for ascending and between C<$_[1]> and C<$_[0]> for
228             descending.
229              
230             Returns the code reference if ordering is ON, a false value if OFF.
231              
232             Note, when object-level ordering is implemented, it is expected that
233             the class-level option will still be available. In that case, any
234             new objects will inherit the class-level ordering unless overridden
235             at the object level.
236              
237             =cut
238              
239             *pairs_order = \ℴ
240             sub order {
241 38     38 1 1632 my( $class, $spec ) = @_; # class not actually used ...
242 38 100       125 return $order unless defined $spec;
243              
244 26 100       62 if( ref( $spec ) eq 'CODE' ) {
245 3         6 $order = $spec;
246             }
247             else {
248             $order = {
249             '' => '', # turn off ordering
250 12     12   39 na => sub{ $_[0] < $_[1] }, # number ascending
251 10     10   35 nd => sub{ $_[1] < $_[0] }, # number descending
252 22     22   71 sa => sub{ $_[0] lt $_[1] }, # string ascending
253 20     20   54 sd => sub{ $_[1] lt $_[0] }, # string descending
254             sna => sub{ # either ascending
255 20 100 100 20   148 looks_like_number($_[0])&&looks_like_number($_[1])?
256             $_[0] < $_[1]: $_[0] lt $_[1] },
257             snd => sub{ # either descending
258 30 100 100 30   213 looks_like_number($_[0])&&looks_like_number($_[1])?
259             $_[1] < $_[0]: $_[1] lt $_[0] },
260 23         407 }->{ $spec };
261 23 50       331 croak "\$spec($spec) not recognized" unless defined $order;
262             }
263 26         65 return $order;
264             }
265              
266             #---------------------------------------------------------------------
267              
268             =head1 OBJECT METHODS
269              
270             =head2 $pairs->set( $key => $value[, $pos] );
271              
272             Sets the value if C<$key> exists; adds a new key/value pair if not.
273              
274             Accepts C<$key>, C<$value>, and optionally, C<$pos>.
275              
276             If C<$pos> is given, and there is a key/value pair at that position,
277             it will be set to C<$key> and C<$value>, I
278             different>. For example:
279              
280             my $pairs = Data::Pairs->new( [{a=>1},{b=>2}] );
281             $pairs->set( c => 3, 0 ); # pairs is now [{c=>3},{b=>2}]
282              
283             (As implied by the example, positions start at 0.)
284              
285             If C<$pos> is given, and there isn't a pair there, a new pair is
286             added there (perhaps overriding a defined ordering).
287              
288             If C<$pos> is not given, the key will be located and if found,
289             the value set. If the key is not found, a new pair is added to the
290             end or merged according to the defined C.
291              
292             Returns C<$value> (as a nod toward $hash{$key}=$value, which
293             "returns" $value).
294              
295             =cut
296              
297             *pairs_set = \&set;
298             sub set {
299 78     78 1 5368 my( $self, $key, $value, $pos ) = @_;
300 78 50       164 return unless defined $key;
301              
302             # you can give a $pos to change a member including changing its key
303              
304             # pos found action
305             # ----- ----- ------
306             # def def -> set key/value at pos
307             # def undef -> set key/value at pos
308             # undef def -> set key/value at found
309             # undef undef -> add key/value (according to order)
310              
311 78         202 my $elem = { $key => $value };
312 78 100       171 if( defined $pos ) {
313 6 100       377 croak "\$pos($pos) too large" if $pos > $#$self+1;
314 4         8 $self->[ $pos ] = $elem;
315 4         15 return $value;
316             }
317              
318 72         134 my $found = pairs_get_pos( $self, $key );
319 72 100       125 if( defined $found ) { $self->[ $found ] = $elem }
  4         8  
320 68         114 else { pairs_add_ordered( $self, $key, $value ) }
321              
322 72         193 $value; # returned
323             }
324              
325             #---------------------------------------------------------------------
326              
327             =head2 $pairs->get_values( [$key[, @keys]] );
328              
329             Get a value or values.
330              
331             Regardless of parameters, if the object is empty, undef is returned in
332             scalar context, an empty list in list context.
333              
334             If no parameters, gets all the values. In scalar context, gives
335             number of values in the object.
336              
337             my $pairs = Data::Pairs->new( [{a=>1},{b=>2},{c=>3},{b=>4},{b=>5}] );
338             my @values = $pairs->get_values(); # (1, 2, 3, 4, 5)
339             my $howmany = $pairs->get_values(); # 5
340              
341             If keys given, their values are returned in the order found
342             in the object, not the order of the given keys.
343              
344             In scalar context, gives the number of values found, e.g.,
345              
346             @values = $pairs->get_values( 'c', 'b' ); # (2, 3, 4, 5)
347             $howmany = $pairs->get_values( 'c', 'b' ); # 4
348              
349             Note, unlike C, because an object may have
350             duplicate keys, this method behaves the same if given one key or
351             many, e.g.,
352              
353             @values = $pairs->get_values( 'b' ); # (2, 4, 5)
354             $howmany = $pairs->get_values( 'b' ); # 3
355              
356             Therefore, always call C in list context to get one
357             or more values.
358              
359             =cut
360              
361             *pairs_get_values = \&get_values;
362             sub get_values {
363 33     33 1 7694 my( $self, @keys ) = @_;
364 33 50       94 return unless @$self;
365              
366 33         36 my @ret;
367 33 100       92 if( @keys ) {
368 25         39 for my $href ( @$self ) {
369 108         174 my ( $key ) = keys %$href;
370 108         144 for ( @keys ) {
371 182 100       365 if( $key eq $_ ) {
372 78         135 my ( $value ) = values %$href;
373 78         81 push @ret, $value;
374 78         138 last;
375             }
376             }
377             }
378             }
379             else {
380 8         18 for my $href ( @$self ) {
381 36         53 my ( $value ) = values %$href;
382 36         51 push @ret, $value;
383             }
384             }
385 33         134 return @ret;
386             }
387              
388             #---------------------------------------------------------------------
389              
390             =head2 $pairs->add( $key => $value[, $pos] );
391              
392             Adds a key/value pair to the object.
393              
394             Accepts C<$key>, C<$value>, and optionally, C<$pos>.
395              
396             If C<$pos> is given, the key/value pair will be added (inserted)
397             there (possibly overriding a defined order), e.g.,
398              
399             my $pairs = Data::Pairs->new( [{a=>1},{b=>2}] );
400             $pairs->add( c => 3, 1 ); # pairs is now [{a=>1},{c=>3},{b=>2}]
401              
402             (Positions start at 0.)
403              
404             If C<$pos> is not given, a new pair is added to the end or merged
405             according to the defined C.
406              
407             Returns C<$value>.
408              
409             =cut
410              
411             *pairs_add = \&add;
412             sub add {
413 32     32 1 11960 my( $self, $key, $value, $pos ) = @_;
414 32 50       92 return unless defined $key;
415              
416 32         81 my $elem = { $key => $value };
417 32 100       70 if( defined $pos ) {
418 8 100       274 croak "\$pos($pos) too large" if $pos > $#$self+1;
419 6         19 splice @$self, $pos, 0, $elem;
420             }
421             else {
422 24         51 pairs_add_ordered( $self, $key, $value );
423             }
424              
425 30         89 $value; # returned
426             }
427              
428             #---------------------------------------------------------------------
429              
430             =head2 pairs_add_ordered( $pairs, $key => $value );
431              
432             Private routine used by C and C; should not be called
433             directly.
434              
435             Accepts C<$key> and C<$value>.
436              
437             Adds a new key/value pair to the end or merged according to the
438             defined C.
439              
440             Has no defined return value.
441              
442             =cut
443              
444             sub pairs_add_ordered {
445 92     92 1 143 my( $self, $key, $value ) = @_;
446 92         212 my $elem = { $key => $value };
447              
448 92 100       189 unless( $order ) { push @$self, $elem; return }
  4         13  
  4         11  
449              
450             # optimization for when members are added in order
451 88 100       217 if( @$self ) {
452 70         72 my ( $key2 ) = keys %{$self->[-1]}; # at the end
  70         144  
453 70 100       367 unless( $order->( $key, $key2 ) ) {
454 22         69 push @$self, $elem;
455 22         44 return;
456             }
457             }
458              
459             # else start comparing at the beginning
460 66         168 for my $i ( 0 .. $#$self ) {
461 62         59 my ( $key2 ) = keys %{$self->[ $i ]};
  62         155  
462 62 100       112 if( $order->( $key, $key2 ) ) { # XXX can we memoize $key in $order->()?
463 48         95 splice @$self, $i, 0, $elem;
464 48         97 return;
465             }
466             }
467              
468 18         68 push @$self, $elem;
469             }
470              
471             #---------------------------------------------------------------------
472              
473             =head2 $pairs->get_pos( $key );
474              
475             Gets position(s) where a key is found.
476              
477             Accepts one key (any extras are silently ignored).
478              
479             In list context, returns a list of positions where the key is found.
480              
481             In scalar context, if the key only appears once, that position is
482             returned. If the key appears more than once, an array ref is returned,
483             which contains all the positions, e.g.,
484              
485             my $pairs = Data::Pairs->new( [{a=>1},{b=>2},{c=>3},{b=>4}] );
486              
487             my @pos = $pairs->get_pos( 'c' ); # (2)
488             my $pos = $pairs->get_pos( 'c' ); # 2
489              
490             @pos = $pairs->get_pos( 'b' ); # (1, 3)
491             $pos = $pairs->get_pos( 'b' ); # [1, 3]
492              
493             Returns C<()/undef> if no key given, no keys found, or object is empty.
494              
495             =cut
496              
497             *pairs_get_pos = \&get_pos;
498             sub get_pos {
499 92     92 1 3748 my( $self, $wantkey ) = @_;
500 92 50       189 return unless $wantkey;
501 92 100       196 return unless @$self;
502 76         107 my @ret;
503 76         171 for my $i ( 0 .. $#$self ) {
504 230         203 my ( $key ) = keys %{$self->[ $i ]};
  230         480  
505 230 100       578 if( $key eq $wantkey ) {
506 28         53 push @ret, $i;
507             }
508             }
509 76 100       214 return unless @ret;
510 22 100       58 return @ret if wantarray;
511 18 100       64 return $ret[0] if @ret == 1;
512 4         14 \@ret; # returned
513             }
514              
515             #---------------------------------------------------------------------
516              
517             =head2 $pairs->get_pos_hash( [@keys] );
518              
519             Gets positions where keys are found.
520              
521             Accepts zero or more keys.
522              
523             In list context, returns a hash of keys/positions found. In scalar
524             context, returns a hash ref to this hash. If no keys given, all the
525             positions are mapped in the hash. Since keys may appear more than
526             once, the positions are stored as arrays.
527              
528             my $pairs = Data::Pairs->new( [{a=>1},{b=>2},{c=>3},{b=>4}] );
529             my %pos = $pairs->get_pos_hash( 'c', 'b' ); # %pos is (b=>[1,3],c=>[2])
530             my $pos_href = $pairs->get_pos_hash( 'c', 'b' ); # $pos_href is {b=>[1,3],c=>[2]}
531              
532             If a given key is not found, it will not appear in the returned hash.
533              
534             Returns C if object is empty.
535              
536             =cut
537              
538             *pairs_get_pos_hash = \&get_pos_hash;
539             sub get_pos_hash {
540 12     12 1 6459 my( $self, @keys ) = @_;
541 12 50       36 return unless @$self;
542 12         15 my %ret;
543 12 100       30 if( @keys ) {
544 8         24 for my $i ( 0 .. $#$self ) {
545 32         38 my ( $key ) = keys %{$self->[ $i ]};
  32         67  
546 32         57 for ( @keys ) {
547 56 100       119 if( $key eq $_ ) {
548 24         24 push @{$ret{ $key }}, $i;
  24         46  
549 24         85 last;
550             }
551             }
552             }
553             }
554             else {
555 4         11 for my $i ( 0 .. $#$self ) {
556 16         19 my ( $key ) = keys %{$self->[ $i ]};
  16         31  
557 16         18 push @{$ret{ $key }}, $i;
  16         40  
558             }
559             }
560 12 100       61 return %ret if wantarray;
561 6         23 \%ret; # returned
562             }
563              
564             #---------------------------------------------------------------------
565              
566             =head2 $pairs->get_keys( [@keys] );
567              
568             Gets keys.
569              
570             Accepts zero or more keys. If no keys are given, returns all the
571             keys in the object (list context) or the number of keys (scalar
572             context), e.g.,
573              
574             my $pairs = Data::Pairs->new( [{a=>1},{b=>2},{c=>3},{b=>4},{b=>5}] );
575             my @keys = $pairs->get_keys(); # @keys is (a, b, c, b, b)
576             my $howmany = $pairs->get_keys(); # $howmany is 5
577              
578             If one or more keys are given, returns all the keys that are found
579             (list) or the number found (scalar). Keys returned are listed in the
580             order found in the object, e.g.,
581              
582             @keys = $pairs->get_keys( 'c', 'b', 'A' ); # @keys is (b, c, b, b)
583             $howmany = $pairs->get_keys( 'c', 'b', 'A' ); # $howmany is 4
584              
585             =cut
586              
587             *pairs_get_keys = \&get_keys;
588             sub get_keys {
589 14     14 1 5151 my( $self, @keys ) = @_;
590 14 50       38 return unless @$self;
591 14         19 my @ret;
592 14 100       31 if( @keys ) {
593 6         33 for my $href ( @$self ) {
594 26         54 my ( $key ) = keys %$href;
595 26         40 for ( @keys ) {
596 52 100       202 if( $key eq $_ ) {
597 22         26 push @ret, $key;
598 22         38 last;
599             }
600             }
601             }
602             }
603             else {
604 8         19 for my $href ( @$self ) {
605 36         53 my ( $key ) = keys %$href;
606 36         62 push @ret, $key;
607             }
608             }
609 14         56 @ret; # returned
610             }
611              
612             #---------------------------------------------------------------------
613              
614             =head2 $pairs->get_array( [@keys] );
615              
616             Gets an array of key/value pairs.
617              
618             Accepts zero or more keys. If no keys are given, returns a list of
619             all the key/value pairs in the object (list context) or an array
620             reference to that list (scalar context), e.g.,
621              
622             my $pairs = Data::Pairs->new( [{a=>1},{b=>2},{c=>3}] );
623             my @array = $pairs->get_array(); # @array is ({a=>1}, {b=>2}, {c=>3})
624             my $aref = $pairs->get_array(); # $aref is [{a=>1}, {b=>2}, {c=>3}]
625              
626             If one or more keys are given, returns a list of key/value pairs for
627             all the keys that are found (list) or an aref to that list (scalar).
628             Pairs returned are in the order found in the object, e.g.,
629              
630             @array = $pairs->get_array( 'c', 'b', 'A' ); # @array is ({b->2}, {c=>3})
631             $aref = $pairs->get_array( 'c', 'b', 'A' ); # @aref is [{b->2}, {c=>3}]
632              
633             Note, conceivably this method might be used to make a copy
634             (unblessed) of the object, but it would not be a deep copy (if values
635             are references, the references would be copied, not the referents).
636              
637             =cut
638              
639             *pairs_get_array = \&get_array;
640             sub get_array {
641 14     14 1 5768 my( $self, @keys ) = @_;
642 14 50       38 return unless @$self;
643 14         17 my @ret;
644 14 100       30 if( @keys ) {
645 6         12 for my $href ( @$self ) {
646 18         30 my ( $key ) = keys %$href;
647 18         26 for ( @keys ) {
648 34 100       73 if( $key eq $_ ) {
649 12         25 push @ret, { %$href };
650 12         27 last;
651             }
652             }
653             }
654             }
655             else {
656 8         16 for my $href ( @$self ) {
657 24         40 my ( $key ) = keys %$href;
658 24         73 push @ret, { %$href };
659             }
660             }
661 14 100       68 return wantarray? @ret: [ @ret ];
662             }
663              
664             #---------------------------------------------------------------------
665              
666             =head2 $pairs->exists( $key );
667              
668             Accepts one key.
669              
670             Returns true if key is found in object, false if not.
671              
672             =cut
673              
674             *pairs_exists = \&exists;
675             sub exists {
676 5     5 1 1648 my( $self, $key ) = @_;
677 5 50       23 return unless @$self;
678 5         14 return defined pairs_get_pos( $self, $key );
679             }
680              
681             #---------------------------------------------------------------------
682              
683             =head2 $pairs->delete( $key[, $pos] );
684              
685             Accepts one key and an optional position.
686              
687             If C<$pos> is given and the key at that position equals C<$key>, that
688             key/value pair will be deleted. Otherwise, the I key/value
689             pair that matches C<$key> will be deleted.
690              
691             If C<$key> occurs multiple times, C must be called multiple
692             times to delete them all.
693              
694             Returns the value from the deleted pair.
695              
696             =cut
697              
698             *pairs_delete = \&delete;
699             sub delete {
700 5     5 1 2779 my( $self, $key, $pos ) = @_;
701 5 50       23 return unless defined $key;
702 5 50       21 return unless @$self;
703              
704 5 100       21 if( defined $pos ) {
705 2         5 my( $foundkey ) = keys %{$self->[ $pos ]};
  2         10  
706 2 50       14 return unless $foundkey eq $key;
707             }
708             else {
709 3         9 $pos = pairs_get_pos( $self, $key );
710 3 50       13 return unless defined $pos;
711             }
712              
713 5         14 my $value = $self->[ $pos ]{ $key };
714 5         14 splice @$self, $pos, 1; # delete it
715 5         19 $value; # returned
716             }
717              
718             #---------------------------------------------------------------------
719              
720             =head2 $pairs->clear();
721              
722             Expects no parameters. Removes all key/value pairs from the object.
723              
724             Returns an empty list.
725              
726             =cut
727              
728             *pairs_clear = \&clear;
729             sub clear {
730 19     19 1 10276 my( $self ) = @_;
731 19         91 @$self = ();
732             }
733              
734             1; # 'use module' return value
735              
736             __END__