File Coverage

blib/lib/Data/Nest.pm
Criterion Covered Total %
statement 70 70 100.0
branch 15 18 83.3
condition 4 4 100.0
subroutine 12 12 100.0
pod 0 7 0.0
total 101 111 90.9


line stmt bran cond sub pod time code
1             package Data::Nest;
2 2     2   34459 use 5.008005;
  2         7  
  2         85  
3 2     2   13 use strict;
  2         6  
  2         78  
4 2     2   22 use warnings;
  2         4  
  2         68  
5 2     2   1013 use Data::Dumper;
  2         6334  
  2         1552  
6              
7             our $VERSION = "0.06";
8              
9             require Exporter;
10             our @ISA = qw/Exporter/;
11             our @EXPORT = qw/nest/;
12              
13             sub new {
14 14     14 0 1050238 my $class = shift;
15 14         37 my %opt = @_;
16              
17 14   100     286 return bless {
      100        
18             keyname => "key",
19             valname => "values",
20             keys => [],
21             rollups => [],
22             tree => {},
23             noValues => $opt{noValues} || 0,
24             delimiter => $opt{delimiter} || "_____",
25             }, $class;
26             }
27              
28             sub nest {
29 1     1 0 4451 my %opt = @_;
30              
31 1         6 my $self = new Data::Nest(%opt);
32 1         5 $self;
33             }
34              
35             sub keyname {
36 1     1 0 3 my $self = shift;
37 1         2 my $keyname = shift;
38 1 50       3 return $self->{keyname} unless($keyname);
39 1         3 $self->{keyname} = $keyname;
40 1         4 $self;
41             }
42              
43             sub valname {
44 1     1 0 3 my $self = shift;
45 1         2 my $valname = shift;
46 1 50       6 return $self->{valname} unless($valname);
47 1         3 $self->{valname} = $valname;
48 1         5 $self;
49             }
50              
51             sub key {
52 24     24 0 163 my $self = shift;
53 24         44 my @keys = @_;
54              
55 24 100       85 return $self->{keys} unless(scalar @keys);
56 18         26 push @{$self->{keys}}, [@keys];
  18         52  
57 18         64 $self;
58             }
59              
60             sub rollup {
61 4     4 0 6 my $self = shift;
62 4         8 my ($name, $func) = @_;
63              
64 4         6 push @{$self->{rollups}}, {name => $name, func => $func};
  4         15  
65 4         11 $self;
66             }
67              
68             sub _entries {
69 1130     1130   1299 my $self = shift;
70 1130         1377 my $array = shift;
71 1130         1161 my $depth = shift;
72 1130 100       1106 return $array if($depth >= scalar @{$self->{keys}});
  1130         3309  
73 473         789 my $key = $self->{keys}[$depth];
74              
75 473         622 my $branch = [];
76 473         531 my %map;
77              
78 473         836 foreach my $obj (@$array){
79 1800 50       2703 my $k = join($self->{delimiter}, map { (ref $_ ne "CODE") ? (exists $obj->{$_} ? $obj->{$_} : $self->{delimiter}) : $_->($obj); } @$key);
  2000 100       7235  
80 1800 100       6192 $map{$k} = [] unless exists $map{$k};
81 1800         1926 push @{$map{$k}}, $obj;
  1800         4205  
82             }
83              
84 473         1429 foreach my $k (sort keys %map){
85 1118         2622 my $values = $self->_entries($map{$k}, $depth+1);
86 1118         1530 my $obj = {};
87 1118         2627 $obj->{$self->{keyname}} = $k;
88 1118         1866 $obj->{$self->{valname}} = $values;
89 1118 100       1358 if($depth + 1 >= scalar @{$self->{keys}}){
  1118         2681  
90 657         1205 foreach my $roll (@{$self->{rollups}}){
  657         1341  
91 400         2430 $obj->{$roll->{name}} = $roll->{func}(@$values);
92             }
93 657 100       3037 if($self->{noValues}){
94 102         248 delete $obj->{$self->{valname}};
95             }
96             }
97 1118         2647 push @$branch, $obj;
98             }
99              
100 473         1531 $branch;
101             }
102              
103             sub entries {
104 12     12 0 2445 my $self = shift;
105 12         18 my $data = shift;
106 12         50 $self->_entries($data, 0);
107             }
108              
109             1;
110             __END__