File Coverage

lib/Class/ParmList.pm
Criterion Covered Total %
statement 157 157 100.0
branch 58 58 100.0
condition 9 9 100.0
subroutine 11 12 91.6
pod 8 8 100.0
total 243 244 99.5


line stmt bran cond sub pod time code
1             package Class::ParmList;
2              
3 3     3   5507 use strict;
  3         16  
  3         85  
4 3     3   14 use warnings;
  3         5  
  3         209  
5              
6             require Exporter;
7              
8             BEGIN {
9 3     3   9 $Class::ParmList::VERSION = '1.06';
10 3         46 @Class::ParmList::ISA = qw (Exporter);
11 3         10 @Class::ParmList::EXPORT = ();
12 3         6 @Class::ParmList::EXPORT_OK = qw (simple_parms parse_parms);
13 3         4651 %Class::ParmList::EXPORT_TAGS = ();
14             }
15              
16             #####################################
17              
18             my $error = '';
19              
20             #####################################
21              
22             sub parse_parms {
23 7     7 1 187 my $package = __PACKAGE__;
24 7         12 my $parms = new($package,@_);
25 7         14 return $parms;
26             }
27              
28             #####################################
29              
30             sub new {
31 25     25 1 348 my $proto = shift;
32 25         29 my $package = __PACKAGE__;
33 25         25 my $class;
34 25 100       47 if (ref($proto)) {
    100          
35 1         2 $class = ref($proto);
36             } elsif ($proto) {
37 23         24 $class = $proto;
38             } else {
39 1         2 $class = $package;
40             }
41 25         39 my $self = bless {},$class;
42              
43             # Clear any outstanding errors
44 25         35 $error = '';
45              
46 25 100       50 unless (-1 != $#_) { # It's legal to pass no parms.
47 6         13 $self->{-name_list} = [];
48 6         10 $self->{-parms} = {};
49 6         18 return $self;
50             }
51              
52 19         25 my $raw_parm_list = {};
53 19         29 my $reftype = ref $_[0];
54 19 100       27 if ($reftype eq 'HASH') {
55 15         25 ($raw_parm_list) = @_;
56             } else {
57 4         13 %$raw_parm_list = @_;
58             }
59              
60             # Transform to lowercase keys on our own parameters
61 19         47 my $parms = { map { (lc($_),$raw_parm_list->{$_}) } keys %$raw_parm_list };
  72         138  
62            
63             # Check for bad parms
64 19         57 my @parm_keys = keys %$parms;
65 19         114 my @bad_parm_keys = grep(!/^-(parms|legal|defaults|required)$/,@parm_keys);
66 19 100       40 unless (-1 == $#bad_parm_keys) {
67 1         4 $error = "Invalid parameters (" . join(',',@bad_parm_keys) . ") passed to Class::ParmList->new\n";
68 1         5 return;
69             }
70              
71              
72             # Legal Parameter names
73 18         39 my ($check_legal, $legal_names);
74 18 100       34 if (defined $parms->{-legal}) {
75 16         17 %$legal_names = map { (lc($_),1) } @{$parms->{-legal}};
  25         72  
  16         25  
76 16         26 $check_legal = 1;
77             } else {
78 2         3 $legal_names = {};
79 2         2 $check_legal = 0;
80             }
81              
82             # Required Parameter names
83 18         21 my ($check_required, $required_names);
84 18 100       30 if ($parms->{-required}) {
85 17         18 foreach my $r_key (@{$parms->{-required}}) {
  17         32  
86 4         7 my $lk = lc ($r_key);
87 4         7 $required_names->{$lk} = 1;
88 4         20 $legal_names->{$lk} = 1;
89             }
90 17         27 $check_required = 1;
91             } else {
92 1         1 $required_names = {};
93 1         2 $check_required = 0;
94             }
95              
96             # Set defaults if needed
97 18         20 my $parm_list;
98 18         47 my $defaults = $parms->{-defaults};
99 18 100       33 if (defined $defaults) {
100 17         65 while (my ($d_key, $d_value) = each %$defaults) {
101 12         17 my $lk = lc ($d_key);
102 12         15 $legal_names->{$lk} = 1;
103 12         33 $parm_list->{$lk} = $d_value;
104             }
105             } else {
106 1         2 $parm_list = {};
107             }
108              
109             # The actual list of parms
110 18         22 my $base_parm_list = $parms->{-parms};
111              
112             # Unwrap references to ARRAY referenced parms
113 18   100     70 while (defined($base_parm_list) && (ref($base_parm_list) eq 'ARRAY')) {
114 4         9 my @data = @$base_parm_list;
115 4 100       10 if ($#data == 0) {
116 2         8 $base_parm_list = $data[0];
117             } else {
118 2         9 $base_parm_list = { @data };
119             }
120             }
121              
122 18 100       28 if (defined ($base_parm_list)) {
123 17         47 while (my ($b_key, $b_value) = each %$base_parm_list) {
124 19         66 $parm_list->{lc($b_key)} = $b_value;
125             }
126             }
127              
128             # Check for Required parameters
129 18 100       30 if ($check_required) {
130 17         31 foreach my $name (keys %$required_names) {
131 4 100       19 unless (exists $parm_list->{$name}) {
132 2         10 $error .= "Required parameter '$name' missing\n";
133             }
134             }
135             }
136              
137             # Check for illegal parameters
138 18         36 my $final_parm_names = [keys %$parm_list];
139 18 100       37 if ($check_legal) {
140 16         20 foreach my $name (@$final_parm_names) {
141 25 100       52 unless (exists $legal_names->{$name}) {
142 3         9 $error .= "Parameter '$name' not legal here.\n";
143             }
144             }
145 16         27 $self->{-legal} = $legal_names;
146             }
147              
148 18 100       44 return unless ($error eq '');
149              
150             # Save the parms for accessing
151 14         20 $self->{-name_list} = $final_parm_names;
152 14         15 $self->{-parms} = $parm_list;
153              
154 14         51 return $self;
155             }
156              
157             #####################################
158              
159             sub get {
160 15     15 1 118 my $self = shift;
161              
162 15         24 my @parmnames = @_;
163 15 100       31 if ($#parmnames == -1) {
164 1         4 require Carp;
165 1         101 Carp::croak(__PACKAGE__ . '::get() called without any parameters');
166             }
167 14         19 my (@results) = ();
168 14         14 my $parmname;
169 14         32 foreach $parmname (@parmnames) {
170 20         27 my $keyname = lc ($parmname);
171 20         67 require Carp;
172 20 100 100     331 Carp::croak (__PACKAGE__ . "::get() called with an illegal named parameter: '$keyname'") if (exists ($self->{-legal}) and not exists ($self->{-legal}->{$keyname}));
173 18         34 push (@results,$self->{-parms}->{$keyname});
174             }
175 12 100       21 if (wantarray) {
176 8         31 return @results;
177             } else {
178 4         23 return $results[$#results];
179             }
180             }
181              
182             #####################################
183              
184             sub exists {
185 3     3 1 90 my $self = shift;
186            
187 3         6 my ($name) = @_;
188              
189 3         4 $name = lc ($name);
190 3         8 return CORE::exists ($self->{-parms}->{$name});
191             }
192              
193             #####################################
194              
195             sub list_parms {
196 2     2 1 7 my $self = shift;
197              
198 2         2 my (@names) = @{$self->{-name_list}};
  2         6  
199              
200 2         6 return @names;
201             }
202              
203             #####################################
204              
205             sub all_parms {
206 1     1 1 8 my $self = shift;
207              
208 1         2 my @parm_list = $self->list_parms;
209 1         2 my $all_p = {};
210 1         3 foreach my $parm (@parm_list) {
211 2         5 $all_p->{$parm} = $self->get($parm);
212             }
213 1         53 return $all_p;
214             }
215              
216             #####################################
217              
218 1     1 1 9 sub error { return $error; }
219              
220             #####################################
221              
222             sub simple_parms {
223 18     18 1 1198 local $SIG{__DIE__} = ''; # Because SOME PEOPLE cause trouble
224 18         28 my $parm_list = shift;
225 18 100       42 unless (ref($parm_list) eq 'ARRAY') {
226 1         6 require Carp;
227 1         347 Carp::confess ('[' . localtime(time) . '] [error] ' . __PACKAGE__ . "::simple_parms() - The first parameter to 'simple_parms()' must be an anonymous list of parameter names.");
228             }
229              
230 17 100 100     58 if (($#_ > 0) && (($#_ + 1) % 2)) {
231 1         5 require Carp;
232 1         133 Carp::confess ('[' . localtime(time) . '] [error] ' . __PACKAGE__ . "::simple_parms() - Odd number of parameter array elements");
233             }
234              
235             # Read any other passed parms
236 16         21 my $parm_ref;
237 16 100       33 if ($#_ == 0) {
    100          
238 9         13 $parm_ref = shift;
239              
240             } elsif ($#_ > 0) {
241 6         19 %$parm_ref = @_;
242             } else {
243 1         2 $parm_ref = {};
244             }
245              
246 16 100       31 unless (ref ($parm_ref) eq 'HASH') {
247 2         10 require Carp;
248 2         287 Carp::confess ('[' . localtime(time) . '] [error] ' . __PACKAGE__ . "::simple_parms() - A bad parameter list was passed (not either an anon hash or an array)");
249             }
250              
251 14         40 my @parm_keys = keys %$parm_ref;
252 14 100       31 if ($#parm_keys != $#$parm_list) {
253 5         25 require Carp;
254 5         686 Carp::confess ('[' . localtime(time) . '] [error] ' . __PACKAGE__ . ":simple_parms() - An incorrect number of parameters were passed");
255             }
256 9 100       15 if ($#parm_keys == -1) {
257 1         5 require Carp;
258 1         158 Carp::croak ('[' . localtime(time) . '] [error] ' . __PACKAGE__ . "::simple_parms() - At least one parameter is required to be requested");
259             }
260              
261 8         34 my @parsed_parms = ();
262 8         14 my $errors = '';
263 8         10 foreach my $parm_name (@$parm_list) {
264 19 100       33 unless (exists $parm_ref->{$parm_name}) {
265 1         4 $errors .= "Parameter $parm_name was not found in passed parameter data.\n";
266 1         2 next;
267             }
268 18         26 push (@parsed_parms,$parm_ref->{$parm_name});
269             }
270 8 100       15 if ($errors ne '') {
271 1         5 require Carp;
272 1         134 Carp::confess ('[' . localtime(time) . '] [error] ' . __PACKAGE__ . "::simple_parms() - $errors");
273             }
274 7 100       11 if (wantarray) {
275 3         16 return @parsed_parms;
276             }
277 4 100       9 unless (0 == $#parsed_parms) {
278 3         13 require Carp;
279 3         365 Carp::croak ('[' . localtime(time) . '] [error] ' . __PACKAGE__ . "::simple_parms() - Requested multiple values in a 'SCALAR' context.");
280             }
281 1         4 return $parsed_parms[0];
282             }
283              
284             #####################################
285              
286             # Keeps 'AUTOLOAD' from sucking cycles during object destruction
287             # Don't laugh. It really happens.
288       0     sub DESTROY {}
289              
290             #####################################
291              
292             1;