File Coverage

lib/Class/ParmList.pm
Criterion Covered Total %
statement 154 155 99.3
branch 58 58 100.0
condition 9 9 100.0
subroutine 10 11 90.9
pod 8 8 100.0
total 239 241 99.1


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