File Coverage

blib/lib/RPerl/DataType/Number.pm
Criterion Covered Total %
statement 72 96 75.0
branch 16 26 61.5
condition 3 6 50.0
subroutine 17 22 77.2
pod 0 7 0.0
total 108 157 68.7


line stmt bran cond sub pod time code
1             # [[[ HEADER ]]]
2             package RPerl::DataType::Number;
3 9     9   56 use strict;
  9         18  
  9         243  
4 9     9   49 use warnings;
  9         18  
  9         206  
5 9     9   48 use RPerl::AfterSubclass;
  9         19  
  9         1196  
6             our $VERSION = 0.009_000;
7              
8             # [[[ OO INHERITANCE ]]]
9 9     9   107 use parent qw(RPerl::DataType::Scalar);
  9         22  
  9         48  
10 9     9   549 use RPerl::DataType::Scalar;
  9         21  
  9         326  
11              
12             # [[[ CRITICS ]]]
13             ## no critic qw(ProhibitUselessNoCritic ProhibitMagicNumbers RequireCheckedSyscalls) # USER DEFAULT 1: allow numeric values & print operator
14             ## no critic qw(RequireInterpolationOfMetachars) # USER DEFAULT 2: allow single-quoted control characters & sigils
15             ## no critic qw(Capitalization ProhibitMultiplePackages ProhibitReusedNames) # SYSTEM DEFAULT 3: allow multiple & lower case package names
16              
17             # [[[ SUB-TYPES ]]]
18             # DEV NOTE, CORRELATION #rp007:
19             # a number is any numeric value, meaning either an integer or a floating-point number;
20             # Boolean, Unsigned Integer, and Integer are all sub-classes of Number;
21             # the hidden Perl semantics are SvIOKp() for ints, and SvNOKp() for numbers;
22             # these numbers appear to act as C doubles and are implemented as such in RPerl;
23             # in the future, this can be optimized (for at least memory usage) by implementing full Float semantics
24             package # hide from PAUSE indexing
25             number;
26 9     9   46 use strict;
  9         20  
  9         188  
27 9     9   52 use warnings;
  9         19  
  9         315  
28 9     9   48 use parent qw(RPerl::DataType::Number);
  9         16  
  9         39  
29              
30             package # hide from PAUSE indexing
31             constant_number;
32 9     9   562 use strict;
  9         20  
  9         186  
33 9     9   54 use warnings;
  9         17  
  9         250  
34 9     9   52 use parent qw(RPerl::DataType::Number);
  9         17  
  9         39  
35              
36             # [[[ PRE-DECLARED TYPES ]]]
37             package # hide from PAUSE indexing
38             boolean;
39             package # hide from PAUSE indexing
40             unsigned_integer;
41             package # hide from PAUSE indexing
42             integer;
43             package # hide from PAUSE indexing
44             character;
45             package # hide from PAUSE indexing
46             string;
47              
48             # [[[ SWITCH CONTEXT BACK TO PRIMARY PACKAGE ]]]
49             package RPerl::DataType::Number;
50 9     9   740 use strict;
  9         24  
  9         187  
51 9     9   52 use warnings;
  9         18  
  9         260  
52              
53             # [[[ INCLUDES ]]]
54 9     9   48 use POSIX qw(floor);
  9         18  
  9         66  
55              
56             # [[[ EXPORTS ]]]
57 9     9   578 use Exporter 'import';
  9         18  
  9         6666  
58             our @EXPORT = qw(number_CHECK number_CHECKTRACE number_to_boolean number_to_unsigned_integer number_to_integer number_to_character number_to_string);
59              
60             # [[[ TYPE-CHECKING ]]]
61             #our void $number_CHECK = sub {
62             sub number_CHECK {
63 0     0 0 0 ( my $possible_number ) = @_;
64 0 0       0 if ( not( defined $possible_number ) ) {
65 0         0 croak(
66             "\nERROR ENV00, TYPE-CHECKING MISMATCH, PERLOPS_PERLTYPES:\nnumber value expected but undefined/null value found,\ncroaking"
67             );
68             }
69 0 0 0     0 if (not( main::RPerl_SvNOKp($possible_number)
70             || main::RPerl_SvIOKp($possible_number) )
71             )
72             {
73 0         0 croak(
74             "\nERROR ENV01, TYPE-CHECKING MISMATCH, PERLOPS_PERLTYPES:\nnumber value expected but non-number value found,\ncroaking"
75             );
76             }
77             }
78             #our void $number_CHECKTRACE = sub {
79             sub number_CHECKTRACE {
80 92     92 0 188 ( my $possible_number, my $variable_name, my $subroutine_name ) = @_;
81 92 100       219 if ( not( defined $possible_number ) ) {
82 4         58 croak(
83             "\nERROR ENV00, TYPE-CHECKING MISMATCH, PERLOPS_PERLTYPES:\nnumber value expected but undefined/null value found,\nin variable $variable_name from subroutine $subroutine_name,\ncroaking"
84             );
85             }
86 88 100 100     424 if (not( main::RPerl_SvNOKp($possible_number)
87             || main::RPerl_SvIOKp($possible_number) )
88             )
89             {
90 6         81 croak(
91             "\nERROR ENV01, TYPE-CHECKING MISMATCH, PERLOPS_PERLTYPES:\nnumber value expected but non-number value found,\nin variable $variable_name from subroutine $subroutine_name,\ncroaking"
92             );
93             }
94             }
95              
96             # [[[ BOOLEANIFY ]]]
97             #our boolean $number_to_boolean = sub {
98             sub number_to_boolean {
99 0     0 0 0 (my number $input_number) = @_;
100             # number_CHECK($input_number);
101 0         0 number_CHECKTRACE( $input_number, '$input_number', 'number_to_boolean()' );
102 0 0       0 if ($input_number == 0) { return 0; }
  0         0  
103 0         0 else { return 1; }
104             }
105              
106             # [[[ UNSIGNED INTEGERIFY ]]]
107             #our unsigned_integer $number_to_unsigned_integer = sub {
108             sub number_to_unsigned_integer {
109 0     0 0 0 (my number $input_number) = @_;
110             # number_CHECK($input_number);
111 0         0 number_CHECKTRACE( $input_number, '$input_number', 'number_to_unsigned_integer()' );
112 0         0 return floor abs $input_number;
113             }
114              
115             # [[[ INTEGERIFY ]]]
116             #our integer $number_to_integer = sub {
117             sub number_to_integer {
118 0     0 0 0 (my number $input_number) = @_;
119             # number_CHECK($input_number);
120 0         0 number_CHECKTRACE( $input_number, '$input_number', 'number_to_integer()' );
121 0         0 return floor $input_number;
122             }
123              
124             # [[[ CHARACTERIFY ]]]
125             #our character $number_to_character = sub {
126             sub number_to_character {
127 0     0 0 0 (my number $input_number) = @_;
128             # number_CHECK($input_number);
129 0         0 number_CHECKTRACE( $input_number, '$input_number', 'number_to_character()' );
130 0         0 my string $tmp_string = number_to_string($input_number);
131 0 0       0 if ($tmp_string eq q{}) { return q{}; }
  0         0  
132 0         0 else { return substr $tmp_string, 0, 1; }
133             }
134              
135             # [[[ STRINGIFY ]]]
136             #our string $number_to_string = sub {
137             sub number_to_string {
138 83     83 0 13682 ( my $input_number ) = @_;
139             # number_CHECK($input_number);
140 83         208 number_CHECKTRACE( $input_number, '$input_number', 'number_to_string()' );
141              
142             # RPerl::diag("in PERLOPS_PERLTYPES number_to_string(), received \$input_number = $input_number\n");
143             # RPerl::diag("in PERLOPS_PERLTYPES number_to_string()...\n");
144             # die 'TMP DEBUG';
145              
146             # DEV NOTE: disable old stringify w/out underscores
147             # return "$input_number";
148              
149             # NEED FIX: if using RPerl data types here, causes errors for `perl -e 'use RPerl::DataType::Integer;'`
150 78         122 my integer $is_negative = 0;
151             # my $is_negative = 0;
152 78 100       185 if ($input_number < 0) { $is_negative = 1; }
  22         38  
153 78         115 my string $retval;
154             # my $retval;
155 78         420 my $split_parts = [ split /[.]/xms, "$input_number" ]; # string_arrayref
156              
157 78 50       213 if ( exists $split_parts->[0] ) {
158 78         148 $retval = reverse $split_parts->[0];
159 78 100       174 if ($is_negative) { chop $retval; } # remove negative sign
  22         43  
160 78         255 $retval =~ s/(\d{3})/$1_/gxms;
161 78 100       209 if ((substr $retval, -1, 1) eq '_') { chop $retval; }
  12         27  
162 78         152 $retval = reverse $retval;
163             }
164             else {
165 0         0 $retval = '0';
166             }
167              
168 78 100       174 if ( exists $split_parts->[1] ) {
169 55         319 $split_parts->[1] =~ s/(\d{3})/$1_/gxms;
170 55 50       170 if ((substr $split_parts->[1], -1, 1) eq '_') { chop $split_parts->[1]; }
  0         0  
171             # if ((substr $split_parts->[1], 0, 1) eq '_') { chop $split_parts->[1]; } # should not be necessary
172 55         112 $retval .= '.' . $split_parts->[1];
173             }
174              
175 78 100       171 if ($is_negative) { $retval = q{-} . $retval; }
  22         45  
176              
177             # RPerl::diag('in PERLOPS_PERLTYPES number_to_string(), have $retval = ' . q{'} . $retval . q{'} . "\n");
178 78         315 return $retval;
179             }
180              
181             # [[[ TYPE TESTING ]]]
182             our number $number__typetest0 = sub {
183             my number $retval
184             = ( 22 / 7 ) + main::RPerl__DataType__Number__MODE_ID(); # return floating-point number value
185              
186             # RPerl::diag("in PERLOPS_PERLTYPES number__typetest0(), have \$retval = $retval\n");
187             return ($retval);
188             };
189             our number $number__typetest1 = sub {
190             ( my number $lucky_number ) = @_;
191             # number_CHECK($lucky_number);
192             number_CHECKTRACE( $lucky_number, '$lucky_number',
193             'number__typetest1()' );
194              
195             # RPerl::diag('in PERLOPS_PERLTYPES number__typetest1(), received $lucky_number = ' . number_to_string($lucky_number) . "\n");
196             return (
197             ( $lucky_number * 2 ) + main::RPerl__DataType__Number__MODE_ID() );
198             };
199              
200             1; # end of class