File Coverage

blib/lib/Params/Validate/Aggregated.pm
Criterion Covered Total %
statement 67 68 98.5
branch 20 24 83.3
condition 2 3 66.6
subroutine 8 9 88.8
pod 1 1 100.0
total 98 105 93.3


line stmt bran cond sub pod time code
1             # --8<--8<--8<--8<--
2             #
3             # Copyright (C) 2011 Smithsonian Astrophysical Observatory
4             #
5             # This file is part of Params::Validate::Aggregated
6             #
7             # Params::Validate::Aggregated is free software: you can redistribute
8             # it and/or modify it under the terms of the GNU General Public
9             # License as published by the Free Software Foundation, either version
10             # 3 of the License, or (at your option) any later version.
11             #
12             # This program is distributed in the hope that it will be useful,
13             # but WITHOUT ANY WARRANTY; without even the implied warranty of
14             # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15             # GNU General Public License for more details.
16             #
17             # You should have received a copy of the GNU General Public License
18             # along with this program. If not, see .
19             #
20             # -->8-->8-->8-->8--
21              
22             package Params::Validate::Aggregated;
23              
24 5     5   203840 use strict;
  5         13  
  5         192  
25 5     5   27 use warnings;
  5         11  
  5         151  
26              
27 5     5   4271 use parent 'Exporter';
  5         2514  
  5         28  
28              
29             our @EXPORT_OK = qw[ pv_disagg ];
30             our @EXPORT_TAGS = ( all => \@EXPORT_OK );
31              
32 5     5   5388 use Params::Validate qw[ :all ];
  5         71299  
  5         1607  
33 5     5   6188 use Data::Alias;
  5         14733  
  5         1944  
34              
35 5     5   47 use Carp;
  5         12  
  5         6735  
36              
37             ## no critic (ProhibitAccessOfPrivateData)
38              
39             our $VERSION = '0.05';
40              
41 0     0   0 sub DESTROY {}
42              
43             our $AUTOLOAD;
44             sub AUTOLOAD {
45              
46 3     3   960 (my $set = $AUTOLOAD) =~ s/.*:://;
47              
48 3         28 my $self = shift;
49              
50 3 50       19 croak( "unknown specification set: $set\n" )
51             unless defined $self->{$set};
52              
53 3 50       10 return wantarray ? %{ $self->{$set} } : $self->{$set};
  3         35  
54             }
55              
56             sub pv_disagg {
57              
58 12     12 1 25243 my %args = validate_with( params => \@_,
59             spec => {
60             params => { type => ARRAYREF,
61             optional => 0,
62             },
63             spec => { type => HASHREF,
64             default => {},
65             },
66             with => { type => HASHREF,
67             default => {},
68             },
69             normalize_keys => { type => CODEREF,
70             optional => 1,
71             },
72             allow_extra => { type => SCALAR,
73             optional => 1,
74             },
75             },
76             allow_extra => 1
77             );
78              
79 12         108 alias my (%upar) = @{$args{params}};
  12         85  
80              
81             # remove the known named parameters. the extra ones are passed
82             # on to Params::Validate;
83 12         49 my ( $params, $spec, $with ) = delete @args{ qw[ params spec with ] };
84              
85             # transform the "spec" parameter specifications to "with" parameter
86             # specifications, adding the extra parameters
87 12         20 my %with = %{$with};
  12         40  
88 12         105 $with{$_} = { spec => $spec->{$_}, %args } for keys %$spec;
89              
90             # keep track of which input parameters were used
91 12         49 my @params = keys %upar;
92 12         29 my %nparams = map { $_ => $_ } @params;
  42         93  
93 12         27 my %used = map { $_ => 0 } @params;
  42         87  
94              
95             # the lists of parameter for each input spec
96 12         24 my %oargs;
97              
98             # whether any input spec had the allow_extra flag set.
99 12         18 my $allow_extra = 0;
100              
101             # memoize normalize_keys functions & results for the input
102             # parameter set.
103 12         18 my %norm;
104              
105             # for each input Params::Validate::validate_with argument list,
106             # 1) track which parameters in the input parameter set are used
107             # 2) create a parameter set containing only those parameters of interest
108              
109 12         53 while ( my ( $fid, $wspec ) = each %with )
110             {
111 36         41 my %fargs;
112              
113 36 100       83 my $normf = exists $wspec->{normalize_keys}
114             ? $wspec->{normalize_keys}
115             : undef;
116              
117             # normalize input parameter set keys
118 36         60 my $npars;
119 36 100       63 if ( defined $normf )
120             {
121 7 100       17 if (exists $norm{$normf} )
122             {
123 4         10 $npars = $norm{$normf};
124             }
125             else
126             {
127 3         27 $npars = { map { $normf->($_) => $_ } @params };
  9         39  
128 3         26 $norm{$normf} = $npars;
129             }
130             }
131             else
132             {
133 29         58 $npars = \%nparams;
134             }
135              
136 36 50       98 my $specs = $wspec->{spec} or croak( "no specs for set $fid\n" );
137              
138             # if allow_extra is set, the entire input parameter set is legit
139 36 100 66     137 if ( exists $wspec->{allow_extra} && $wspec->{allow_extra} )
140             {
141 10         17 $allow_extra++;
142              
143 10         159 alias +(%fargs) = (%upar);
144 10         39 while ( my ( $par, $spec ) = each %$specs )
145             {
146 20 50       35 my $npar = $normf ? $normf->($par) : $par;
147 20 100       92 $used{$npars->{$npar}}++ if exists $npars->{$npar};
148             }
149             }
150             else
151             {
152 26         113 while ( my ( $par, $spec ) = each %$specs )
153             {
154 52 100       96 my $npar = $normf ? $normf->($par) : $par;
155 52 100       173 if ( exists $npars->{$npar} )
156             {
157 44         56 my $ppar = $npars->{$npar};
158 44         85 $used{$ppar}++ ;
159 44         182 alias $fargs{$ppar} = $upar{$ppar};
160             }
161             }
162             }
163              
164 36         145 $oargs{$fid} = \%fargs;
165             }
166              
167 12 100       64 return \%oargs, {} if $allow_extra;
168              
169 8         21 delete @upar{ grep { $used{$_} } keys %used };
  28         61  
170              
171 8         83 return bless(\%oargs, __PACKAGE__), \%upar;
172             }
173              
174             1;
175              
176              
177             __END__