File Coverage

blib/lib/Data/InputMonster/Util.pm
Criterion Covered Total %
statement 26 29 89.6
branch 14 18 77.7
condition 7 9 77.7
subroutine 6 7 85.7
pod 1 1 100.0
total 54 64 84.3


line stmt bran cond sub pod time code
1 1     1   61232 use strict;
  1         10  
  1         29  
2 1     1   4 use warnings;
  1         2  
  1         61  
3             package Data::InputMonster::Util 0.011;
4             # ABSTRACT: handy routines for use with the input monster
5 1     1   493 use Sub::Exporter::Util qw(curry_method);
  1         17983  
  1         7  
6              
7 1         3 use Sub::Exporter -setup => {
8             exports => {
9             dig => curry_method,
10             },
11 1     1   218 };
  1         2  
12              
13             #pod =head1 DESCRIPTION
14             #pod
15             #pod These methods, which provide some helpers for use with InputMonster, can be
16             #pod exported as routines upon request.
17             #pod
18             #pod =cut
19              
20             #pod =method dig
21             #pod
22             #pod my $source = dig( [ $key1, $key2, $key2 ]);
23             #pod my $source = dig( sub { ... } );
24             #pod
25             #pod A C source looks through the input using the given locator. If it's a
26             #pod coderef, the code is called and passed the input. If it's an arrayref, each
27             #pod entry is used, in turn, to subscript the input as a deep data structure. If
28             #pod it's a plain scalar, it's treated like a one-element arrayref would have been.
29             #pod
30             #pod For example, given:
31             #pod
32             #pod $input = [ { ... }, { ... }, { foo => [ { bar => 13, baz => undef } ] } ];
33             #pod $source = dig( [ qw( 2 foo 0 bar ) ] );
34             #pod
35             #pod The source would find 13.
36             #pod
37             #pod =cut
38              
39             sub dig {
40 5     5 1 517 my ($self, $locator) = @_;
41            
42 5 50       12 Carp::confess("no locator given") unless defined $locator;
43              
44 5 100       12 $locator = [ $locator ] unless ref $locator;
45              
46 5 50       18 if (ref $locator eq 'CODE') {
    50          
47 0     0   0 return sub { $locator->($_[1]) };
  0         0  
48             } elsif (ref $locator eq 'ARRAY') {
49             return sub {
50 5     5   12 my ($monster, $input) = @_;
51 5         6 my $next = $input;
52              
53 5         8 for my $k (@$locator) {
54 14 100       27 return unless my $ref = ref $next;
55 13 50 66     41 return unless $ref and (($ref eq 'ARRAY') or ($ref eq 'HASH'));
      66        
56              
57 13 100 100     56 return if $ref eq 'ARRAY' and $k !~ /\A-?\d+\z/;
58 12 100       23 $next = $next->[ $k ] if $ref eq 'ARRAY';
59 12 100       22 $next = $next->{ $k } if $ref eq 'HASH';
60             }
61              
62 3         13 return $next;
63 5         30 };
64             }
65              
66 0           Carp::confess("locator must be either a code or array reference");
67             }
68              
69             'hi, domm!';
70              
71             __END__