File Coverage

blib/lib/Params/Get.pm
Criterion Covered Total %
statement 71 74 95.9
branch 40 44 90.9
condition 23 24 95.8
subroutine 6 6 100.0
pod 1 1 100.0
total 141 149 94.6


line stmt bran cond sub pod time code
1             package Params::Get;
2              
3 5     5   739301 use strict;
  5         10  
  5         208  
4 5     5   29 use warnings;
  5         10  
  5         287  
5              
6 5     5   24 use Carp;
  5         10  
  5         315  
7 5     5   2940 use Devel::Confess;
  5         49438  
  5         21  
8 5     5   398 use Scalar::Util;
  5         7  
  5         2966  
9              
10             our @ISA = qw(Exporter);
11             our @EXPORT_OK = qw(get_params);
12              
13             =head1 NAME
14              
15             Params::Get - Get the parameters to a subroutine in any way you want
16              
17             =head1 VERSION
18              
19             Version 0.13
20              
21             =cut
22              
23             our $VERSION = '0.13';
24              
25             =head1 DESCRIPTION
26              
27             Exports a single function, C, which returns a given value.
28             If a validation schema is provided, the value is validated using
29             L.
30             If validation fails, it croaks.
31              
32             When used hand-in-hand with L you should be able to formally specify the input and output sets for a method.
33              
34             =head1 SYNOPSIS
35              
36             use Params::Get;
37             use Params::Validate::Strict;
38              
39             sub where_am_i
40             {
41             my $params = Params::Validate::Strict::validate_strict({
42             args => Params::Get::get_params(undef, \@_),
43             schema => {
44             'latitude' => {
45             type => 'number',
46             min => -180,
47             max => 180
48             }, 'longitude' => {
49             type => 'number',
50             min => -180,
51             max => 180
52             }
53             }
54             });
55              
56             print 'You are at ', $params->{'latitude'}, ', ', $params->{'longitude'}, "\n";
57             }
58              
59             where_am_i(latitude => 0.3, longitude => 124);
60             where_am_i({ latitude => 3.14, longitude => -155 });
61              
62             =head1 METHODS
63              
64             =head2 get_params
65              
66             Parse the arguments given to a function.
67             Processes arguments passed to methods and ensures they are in a usable format,
68             allowing the caller to call the function in any way that they want
69             e.g. `foo('bar')`, `foo(arg => 'bar')`, `foo({ arg => 'bar' })` all mean the same
70             when called with
71              
72             get_params('arg', @_);
73              
74             or
75              
76             get_params('arg', \@_);
77              
78             Some people like this sort of model, which is also supported.
79              
80             use MyClass;
81              
82             my $str = 'hello world';
83             my $obj = MyClass->new($str, { type => 'string' });
84              
85             package MyClass;
86              
87             use Params::Get;
88              
89             sub new {
90             my $class = shift;
91             my $rc = Params::Get::get_params('value', \@_);
92              
93             return bless $rc, $class;
94             }
95              
96             =cut
97              
98             sub get_params
99             {
100             # Directly return hash reference if the only parameter is a hash reference
101 59 100 100 59 1 930043 return $_[0] if((scalar(@_) == 1) && (ref($_[0]) eq 'HASH')); # Note - doesn't check if "default" was given
102              
103 57         104 my $default = shift;
104              
105 57         132 my $args;
106             my $array_ref;
107 57 100 100     220 if((scalar(@_) == 1) && (ref($_[0]) eq 'ARRAY')) {
108 21 100 100     52 if($default && (scalar(@{$_[0]}) == 2) && (@{$_[0]}[0] eq $default) && (!ref(@{$_[0]}[1]))) {
  14   100     52  
  8   100     34  
  3         11  
109             # in main:
110             # routine('country' => 'US');
111             # in routine():
112             # $params = Params::Get::get_params('country', \@);
113 2         3 return { $default => @{$_[0]}[1] };
  2         9  
114             }
115 19         24 $args = $_[0];
116 19         26 $array_ref = 1;
117             } else {
118 36         60 $args = \@_;
119             }
120              
121 55         64 my $num_args = scalar(@{$args});
  55         86  
122              
123             # Populate %rc based on the number and type of arguments
124 55 100       114 if($num_args == 1) {
125 30 100       48 if(defined($default)) {
126 17 100       38 if(!ref($args->[0])) {
127             # %rc = ($default => shift);
128 5         39 return { $default => $args->[0] };
129             }
130 12 100       33 if(ref($args->[0]) eq 'ARRAY') {
131 1         4 return { $default => $args->[0] };
132             }
133 11 100       24 if(ref($args->[0]) eq 'SCALAR') {
134 3         6 return { $default => ${$args->[0]} };
  3         22  
135             }
136 8 100       20 if(ref($args->[0]) eq 'CODE') {
137 2         12 return { $default => $args->[0] };
138             }
139 6 100       13 if(Scalar::Util::blessed($args->[0])) {
140 2         18 return { $default => $args->[0] };
141             }
142             }
143 17 100       36 if(!defined($args->[0])) {
144 1         7 return;
145             }
146 16 100       39 if(ref($args->[0]) eq 'REF') {
147 1         1 $args->[0] = ${$args->[0]};
  1         2  
148             }
149 16 100       32 if(ref($args->[0]) eq 'HASH') {
150 14         60 return $args->[0];
151             }
152 2 100 66     8 if((ref($args->[0]) eq 'ARRAY') && (scalar(@{$args->[0]}) == 0)) {
  1         4  
153             # in main:
154             # routine('countries' => []);
155             # in routine():
156             # $params = Params::Get::get_params('countries', \@);
157 1 50       3 if(defined($default)) {
158 0         0 return { $default => [] }
159             }
160 1         2 return $args->[0];
161             }
162 1         20 Carp::croak('Usage: ', __PACKAGE__, '->', (caller(1))[3], '()');
163             }
164 25 100       62 if($num_args == 0) {
165 7 100       14 if(defined($default)) {
166             # if(defined($_[0]) && (ref($_[0]) eq 'ARRAY')) {
167             # FIXME
168             # return { $default => [] };
169             # }
170             # FIXME: No means to say that the default is optional
171             # Carp::croak('Usage: ', __PACKAGE__, '->', (caller(1))[3], "($default => \$val)");
172 4         85 Carp::croak(Devel::Confess::longmess('Usage: ', __PACKAGE__, '->', (caller(1))[3], "($default => \$val)"));
173             }
174 3         18 return;
175             }
176 18 100 100     72 if(($num_args == 2) && (ref($args->[1]) eq 'HASH')) {
177 4 50       12 if(defined($default)) {
178 4 50       15 if(scalar keys %{$args->[1]}) {
  4         13  
179             # Obj->new('foo', { 'key1' => 'val1' } - set foo to the mandatory first argument, and the rest are options
180             return {
181             $default => $args->[0],
182 4         7 %{$args->[1]}
  4         28  
183             };
184             }
185             # Obj->new(foo => {}) - set foo to be an empty hash
186 0         0 return { $default => $args->[1] }
187             }
188             }
189              
190 14 100 100     44 if($array_ref && defined($default)) {
191 4         22 return { $default => $args };
192             }
193 10 50       36 if(($num_args % 2) == 0) {
194 10         13 my %rc = @{$args};
  10         39  
195 10         76 return \%rc;
196             }
197              
198 0           Carp::croak('Usage: ', __PACKAGE__, '->', (caller(1))[3], '()');
199             }
200              
201             =head1 AUTHOR
202              
203             Nigel Horne, C<< >>
204              
205             =head1 BUGS
206              
207             Sometimes giving an array ref rather than array fails.
208              
209             =head1 SEE ALSO
210              
211             =over 4
212              
213             =item * L
214              
215             =item * L
216              
217             =back
218              
219             =head1 SUPPORT
220              
221             This module is provided as-is without any warranty.
222              
223             Please report any bugs or feature requests to C,
224             or through the web interface at
225             L.
226             I will be notified, and then you'll
227             automatically be notified of progress on your bug as I make changes.
228              
229             You can find documentation for this module with the perldoc command.
230              
231             perldoc Params::Get
232              
233             You can also look for information at:
234              
235             =over 4
236              
237             =item * MetaCPAN
238              
239             L
240              
241             =item * RT: CPAN's request tracker
242              
243             L
244              
245             =item * CPAN Testers' Matrix
246              
247             L
248              
249             =item * CPAN Testers Dependencies
250              
251             L
252              
253             =back
254              
255             =head1 LICENSE AND COPYRIGHT
256              
257             Copyright 2025 Nigel Horne.
258              
259             This program is released under the following licence: GPL2
260              
261             =cut
262              
263             1;
264              
265             __END__