File Coverage

blib/lib/Mo/utils/Number/Range.pm
Criterion Covered Total %
statement 60 60 100.0
branch 26 26 100.0
condition 21 21 100.0
subroutine 13 13 100.0
pod 6 6 100.0
total 126 126 100.0


line stmt bran cond sub pod time code
1             package Mo::utils::Number::Range;
2              
3 18     18   262739 use base qw(Exporter);
  18         47  
  18         2812  
4 18     18   136 use strict;
  18         39  
  18         707  
5 18     18   196 use warnings;
  18         46  
  18         1281  
6              
7 18     18   11651 use Error::Pure qw(err);
  18         75829  
  18         471  
8 18         447 use Mo::utils::Number qw(check_int check_natural check_number check_percent
9 18     18   11413 check_positive_decimal check_positive_natural);
  18         59  
10 18     18   2112 use Readonly;
  18         35  
  18         17203  
11              
12             Readonly::Array our @EXPORT_OK => qw(check_int_range check_natural_range
13             check_number_range check_percent_range check_positive_decimal_range
14             check_positive_natural_range);
15              
16             our $VERSION = 0.10;
17              
18             # ... -2, -1, 0, 1, 2, ...
19             sub check_int_range {
20 45     45 1 307944 my ($self, $key, $min, $max) = @_;
21              
22 45 100       204 _check_key($self, $key) && return;
23              
24 35         144 check_int($self, $key);
25              
26 25 100 100     132 if ($self->{$key} < $min || $self->{$key} > $max) {
27             err "Parameter '".$key."' must be a integer between $min and $max.",
28 10         2037 'Value', $self->{$key},
29             ;
30             }
31              
32 15         41 return;
33             }
34              
35             # 0, 1, 2 ...
36             sub check_natural_range {
37 48     48 1 345903 my ($self, $key, $min, $max) = @_;
38              
39 48 100       323 _check_key($self, $key) && return;
40              
41 38         292 check_natural($self, $key);
42              
43 23 100 100     176 if ($self->{$key} < $min || $self->{$key} > $max) {
44             err "Parameter '".$key."' must be a natural number between $min and $max.",
45 6         667 'Value', $self->{$key},
46             ;
47             }
48              
49 17         49 return;
50             }
51              
52             # Common number.
53             sub check_number_range {
54 10     10 1 325661 my ($self, $key, $min, $max) = @_;
55              
56 10 100       81 _check_key($self, $key) && return;
57              
58 8         26 check_number($self, $key);
59              
60 7 100 100     25 if ($self->{$key} < $min || $self->{$key} > $max) {
61             err "Parameter '".$key."' must be a number between $min and $max.",
62 2         10 'Value', $self->{$key},
63             ;
64             }
65              
66 5         10 return;
67             }
68              
69             sub check_percent_range {
70 10     10 1 372152 my ($self, $key, $min, $max) = @_;
71              
72 10 100       117 _check_key($self, $key) && return;
73              
74 8         40 check_percent($self, $key);
75              
76 5         21 my $value = $self->{$key};
77 5         27 $value =~ s/%$//ms;
78 5 100 100     27 if ($value < $min || $value > $max) {
79             err "Parameter '".$key."' must be a percent between $min% and $max%.",
80 2         13 'Value', $self->{$key},
81             ;
82             }
83              
84 3         11 return;
85             }
86              
87             sub check_positive_decimal_range {
88 13     13 1 311704 my ($self, $key, $min, $max) = @_;
89              
90 13 100       179 _check_key($self, $key) && return;
91              
92 11         50 check_positive_decimal($self, $key);
93              
94 8 100 100     30 if ($self->{$key} < $min || $self->{$key} > $max) {
95             err "Parameter '".$key."' must be a positive decimal number between $min and $max.",
96 2         13 'Value', $self->{$key},
97             ;
98             }
99              
100 6         9 return;
101             }
102              
103             # 1, 2 ...
104             sub check_positive_natural_range {
105 10     10 1 414829 my ($self, $key, $min, $max) = @_;
106              
107 10 100       112 _check_key($self, $key) && return;
108              
109 8         41 check_positive_natural($self, $key);
110              
111 5 100 100     23 if ($self->{$key} < $min || $self->{$key} > $max) {
112             err "Parameter '".$key."' must be a positive natural number between $min and $max.",
113 2         13 'Value', $self->{$key},
114             ;
115             }
116              
117 3         10 return;
118             }
119              
120             sub _check_key {
121 136     136   358 my ($self, $key) = @_;
122              
123 136 100 100     868 if (! exists $self->{$key} || ! defined $self->{$key}) {
124 28         140 return 1;
125             }
126              
127 108         314 return 0;
128             }
129              
130             1;
131              
132             __END__
133              
134             =pod
135              
136             =encoding utf8
137              
138             =head1 NAME
139              
140             Mo::utils::Number::Range - Mo number utilities for ranges.
141              
142             =head1 SYNOPSIS
143              
144             use Mo::utils::Number::Range qw(check_int_range check_natural_range check_number_range check_percent_range check_positive_natural_range);
145              
146             check_int_range($self, $key, $min, $max);
147             check_natural_range($self, $key, $min, $max);
148             check_number_range($self, $key, $min, $max);
149             check_percent_range($self, $key, $min, $max);
150             check_positive_decimal_range($self, $key, $min, $max);
151             check_positive_natural_range($self, $key, $min, $max);
152              
153             =head1 DESCRIPTION
154              
155             Mo number range utilities for checking of data objects.
156              
157             =head1 SUBROUTINES
158              
159             =head2 C<check_int_range>
160              
161             check_int_range($self, $key, $min, $max);
162              
163             I<Since version 0.03.>
164              
165             Check parameter defined by C<$key> if it's in range of integer numbers (... -2, -1, 0, 1, 2, ...).
166             Value could be undefined or doesn't exist.
167              
168             Returns undef.
169              
170             =head2 C<check_natural_range>
171              
172             check_natural_range($self, $key, $min, $max);
173              
174             I<Since version 0.03.>
175              
176             Check parameter defined by C<$key> if it's in range of natural numbers (0, 1, 2, ...).
177             Value could be undefined or doesn't exist.
178              
179             Returns undef.
180              
181             =head2 C<check_number_range>
182              
183             check_number_range($self, $key, $min, $max);
184              
185             I<Since version 0.03.>
186              
187             Check parameter defined by C<$key> which is in range of numbers (positive or negative) or not.
188             Number could be integer, float, exponencial and negative.
189             Implementation is via L<Scalar::Util/looks_like_number>.
190              
191             Put error if check isn't ok.
192              
193             Returns undef.
194              
195             =head2 C<check_percent_range>
196              
197             check_percent_range($self, $key, $min, $max);
198              
199             I<Since version 0.03.>
200              
201             Check parameter defined by C<$key> if it's in range of percent numbers.
202             Value could be undefined or doesn't exist.
203              
204             Returns undef.
205              
206             =head2 C<check_positive_decimal_range>
207              
208             check_positive_decimal_range($self, $key, $min, $max);
209              
210             I<Since version 0.07.>
211              
212             Check parameter defined by C<$key> if it's in range of positive decimal numbers.
213             Value could be undefined or doesn't exist.
214              
215             Returns undef.
216              
217             =head2 C<check_positive_natural_range>
218              
219             check_positive_natural_range($self, $key, $min, $max);
220              
221             I<Since version 0.03.>
222              
223             Check parameter defined by C<$key> if it's in range of positive natural numbers (1, 2, ...).
224             Value could be undefined or doesn't exist.
225              
226             Returns undef.
227              
228             =head1 ERRORS
229              
230             check_int_range():
231             Parameter '%s' must be a integer.
232             Value: %s
233             Parameter '%s' must be a integer between %s and %s.
234             Value: %s
235             check_natural_range():
236             Parameter '%s' must be a natural number.
237             Value: %s
238             Parameter '%s' must be a natural number between %s and %s.
239             Value: %s
240             check_number_range():
241             Parameter '%s' must be a number.
242             Value: %s
243             Parameter '%s' must be a number between %s and %s.
244             Value: %s
245             check_percent_range():
246             Parameter '%s' has bad percent value.
247             Value: %s
248             Parameter '%s' has bad percent value (missing %).
249             Value: %s
250             Parameter '%s' must be a percent between %s% and %s%.
251             Value: %s
252             check_positive_decimal_range():
253             Parameter '%s' must be a positive decimal number.
254             Value: %s
255             Parameter '%s' must be a positive decimal number between %s and %s.
256             Value: %s
257             check_positive_natural_range():
258             Parameter '%s' must be a positive natural number.
259             Value: %s
260             Parameter '%s' must be a positive natural number between %s and %s.
261             Value: %s
262              
263             =head1 EXAMPLE1
264              
265             =for comment filename=check_int_range_ok.pl
266              
267             use strict;
268             use warnings;
269              
270             use Mo::utils::Number::Range qw(check_int_range);
271              
272             my $self = {
273             'key' => -2,
274             };
275             check_int_range($self, 'key', -3, -1);
276              
277             # Print out.
278             print "ok\n";
279              
280             # Output:
281             # ok
282              
283             =head1 EXAMPLE2
284              
285             =for comment filename=check_int_range_fail.pl
286              
287             use strict;
288             use warnings;
289              
290             use Error::Pure;
291             use Mo::utils::Number::Range qw(check_int_range);
292              
293             $Error::Pure::TYPE = 'Error';
294              
295             my $self = {
296             'key' => -2,
297             };
298             check_int_range($self, 'key', 1, 2);
299              
300             # Print out.
301             print "ok\n";
302              
303             # Output like:
304             # #Error [...Range.pm:?] Parameter 'key' must be a integer between 1 and 2.
305              
306             =head1 EXAMPLE3
307              
308             =for comment filename=check_natural_range_ok.pl
309              
310             use strict;
311             use warnings;
312              
313             use Mo::utils::Number::Range qw(check_natural_range);
314              
315             my $self = {
316             'key' => 0,
317             };
318             check_natural_range($self, 'key', -1, 1);
319              
320             # Print out.
321             print "ok\n";
322              
323             # Output:
324             # ok
325              
326             =head1 EXAMPLE4
327              
328             =for comment filename=check_natural_range_fail.pl
329              
330             use strict;
331             use warnings;
332              
333             use Error::Pure;
334             use Mo::utils::Number::Range qw(check_natural_range);
335              
336             $Error::Pure::TYPE = 'Error';
337              
338             my $self = {
339             'key' => 4,
340             };
341             check_natural_range($self, 'key', 0, 3);
342              
343             # Print out.
344             print "ok\n";
345              
346             # Output like:
347             # #Error [...Range.pm:?] Parameter 'key' must be a natural number between 0 and 3.
348              
349             =head1 EXAMPLE5
350              
351             =for comment filename=check_number_range_ok.pl
352              
353             use strict;
354             use warnings;
355              
356             use Mo::utils::Number::Range qw(check_number_range);
357              
358             my $self = {
359             'key' => '10',
360             };
361             check_number_range($self, 'key', 1.1, 11);
362              
363             # Print out.
364             print "ok\n";
365              
366             # Output:
367             # ok
368              
369             =head1 EXAMPLE6
370              
371             =for comment filename=check_number_range_fail.pl
372              
373             use strict;
374             use warnings;
375              
376             $Error::Pure::TYPE = 'Error';
377              
378             use Mo::utils::Number::Range qw(check_number_range);
379              
380             my $self = {
381             'key' => 11,
382             };
383             check_number_range($self, 'key', 1, 10);
384              
385             # Print out.
386             print "ok\n";
387              
388             # Output like:
389             # #Error [...Range.pm:?] Parameter 'key' must be a number between 1 and 10.
390              
391             =head1 EXAMPLE7
392              
393             =for comment filename=check_percent_range_ok.pl
394              
395             use strict;
396             use warnings;
397              
398             use Mo::utils::Number::Range qw(check_percent_range);
399              
400             my $self = {
401             'key' => '10%',
402             };
403             check_percent_range($self, 'key', 1.1, 11);
404              
405             # Print out.
406             print "ok\n";
407              
408             # Output:
409             # ok
410              
411             =head1 EXAMPLE8
412              
413             =for comment filename=check_percent_range_fail.pl
414              
415             use strict;
416             use warnings;
417              
418             $Error::Pure::TYPE = 'Error';
419              
420             use Mo::utils::Number::Range qw(check_percent_range);
421              
422             my $self = {
423             'key' => 11,
424             };
425             check_percent_range($self, 'key', 1, 10);
426              
427             # Print out.
428             print "ok\n";
429              
430             # Output like:
431             # #Error [...Range.pm:?] Parameter 'key' has bad percent value (missing %).
432              
433             =head1 EXAMPLE9
434              
435             =for comment filename=check_positive_natural_range_ok.pl
436              
437             use strict;
438             use warnings;
439              
440             use Mo::utils::Number::Range qw(check_positive_natural_range);
441              
442             my $self = {
443             'key' => '10',
444             };
445             check_positive_natural_range($self, 'key', 1.1, 11);
446              
447             # Print out.
448             print "ok\n";
449              
450             # Output:
451             # ok
452              
453             =head1 EXAMPLE10
454              
455             =for comment filename=check_positive_natural_range_fail.pl
456              
457             use strict;
458             use warnings;
459              
460             $Error::Pure::TYPE = 'Error';
461              
462             use Mo::utils::Number::Range qw(check_positive_natural_range);
463              
464             my $self = {
465             'key' => -2,
466             };
467             check_positive_natural_range($self, 'key', 1, 10);
468              
469             # Print out.
470             print "ok\n";
471              
472             # Output like:
473             # #Error [...Range.pm:?] Parameter 'key' must be a positive natural number.
474              
475             =head1 DEPENDENCIES
476              
477             L<Error::Pure>,
478             L<Exporter>,
479             L<Mo::utils::Number>,
480             L<Readonly>.
481              
482             =head1 SEE ALSO
483              
484             =over
485              
486             =item L<Mo::utils::Number>
487              
488             Mo number utilities.
489              
490             =item L<Mo>
491              
492             Micro Objects. Mo is less.
493              
494             =item L<Mo::utils>
495              
496             Mo utilities.
497              
498             =back
499              
500             =head1 REPOSITORY
501              
502             L<https://github.com/michal-josef-spacek/Mo-utils-Number>
503              
504             =head1 AUTHOR
505              
506             Michal Josef Špaček L<mailto:skim@cpan.org>
507              
508             L<http://skim.cz>
509              
510             =head1 LICENSE AND COPYRIGHT
511              
512             © 2024-2026 Michal Josef Špaček
513              
514             BSD 2-Clause License
515              
516             =head1 VERSION
517              
518             0.10
519              
520             =cut