File Coverage

blib/lib/RPerl/DataStructure/Hash/SubTypes.pm
Criterion Covered Total %
statement 345 421 81.9
branch 30 62 48.3
condition 3 6 50.0
subroutine 72 77 93.5
pod n/a
total 450 566 79.5


line stmt bran cond sub pod time code
1             ## no critic qw(ProhibitUselessNoCritic PodSpelling ProhibitExcessMainComplexity) # DEVELOPER DEFAULT 1a: allow unreachable & POD-commented code; SYSTEM SPECIAL 4: allow complex code outside subroutines, must be on line 1
2             package RPerl::DataStructure::Hash::SubTypes;
3 7     7   46 use strict;
  7         17  
  7         202  
4 7     7   50 use warnings;
  7         17  
  7         164  
5 7     7   32 use RPerl::AfterSubclass;
  7         15  
  7         968  
6             our $VERSION = 0.014_000;
7              
8             # [[[ CRITICS ]]]
9             ## no critic qw(ProhibitUselessNoCritic ProhibitMagicNumbers RequireCheckedSyscalls) # USER DEFAULT 1: allow numeric values & print operator
10             ## no critic qw(ProhibitUnreachableCode RequirePodSections RequirePodAtEnd) # DEVELOPER DEFAULT 1b: allow unreachable & POD-commented code, must be after line 1
11             ## no critic qw(RequireInterpolationOfMetachars) # USER DEFAULT 2: allow single-quoted control characters & sigils
12             ## no critic qw(Capitalization ProhibitMultiplePackages ProhibitReusedNames) # SYSTEM DEFAULT 3: allow multiple & lower case package names
13              
14             # [[[ EXPORTS ]]]
15 7     7   48 use RPerl::Exporter 'import';
  7         14  
  7         45  
16             our @EXPORT = qw(hashref_CHECK hashref_CHECKTRACE integer_hashref_CHECK integer_hashref_CHECKTRACE number_hashref_CHECK number_hashref_CHECKTRACE string_hashref_CHECK string_hashref_CHECKTRACE integer_hashref_to_string number_hashref_to_string string_hashref_to_string);
17             our @EXPORT_OK = qw(integer_hashref__typetest0 integer_hashref__typetest1 number_hashref__typetest0 number_hashref__typetest1 string_hashref__typetest0 string_hashref__typetest1);
18              
19             # [[[ INCLUDES ]]]
20 7     7   40 use RPerl::DataType::Integer; # integer_CHECKTRACE
  7         13  
  7         48  
21              
22             # [[[ HASHES ]]]
23              
24             # a hash is an associative array, meaning a 1-dimensional list/vector/sequence/set of (key, value) pairs;
25             # we never use this type directly, instead we always use the hashref type,
26             # per LMPC #27: Thou Shalt Not Use Direct Access To Arrays & Hashes Stored In @ Or % Non-Scalar Variables
27             package # hide from PAUSE indexing
28             hash;
29 7     7   44 use strict;
  7         16  
  7         159  
30 7     7   39 use warnings;
  7         12  
  7         240  
31 7     7   38 use parent qw(RPerl::DataStructure::Hash);
  7         14  
  7         37  
32              
33             # [[[ HASH REF ]]]
34             # [[[ HASH REF ]]]
35             # [[[ HASH REF ]]]
36              
37             # ref to hash
38             package # hide from PAUSE indexing
39             hashref;
40 7     7   487 use strict;
  7         19  
  7         132  
41 7     7   31 use warnings;
  7         16  
  7         272  
42             #use parent -norequire, qw(ref); # NEED REMOVE: properly replaced by line below?
43 7     7   42 use parent -norequire, qw(RPerl::DataStructure::Hash::Reference);
  7         14  
  7         33  
44 7     7   307 use Carp;
  7         12  
  7         410  
45              
46             # [[[ SWITCH CONTEXT BACK TO PRIMARY PACKAGE FOR EXPORT TO WORK ]]]
47             package RPerl::DataStructure::Hash::SubTypes;
48 7     7   41 use strict;
  7         15  
  7         133  
49 7     7   32 use warnings;
  7         18  
  7         173  
50              
51 7     7   38 use RPerl::Config; # for 'use English;' etc.
  7         13  
  7         2246  
52              
53             # [[[ TYPE-CHECKING ]]]
54              
55             sub hashref_CHECK {
56 0     0   0 { my void $RETURN_TYPE };
  0         0  
57 0         0 ( my $possible_hashref ) = @ARG;
58 0 0       0 if ( not( defined $possible_hashref ) ) {
59 0         0 croak(
60             "\nERROR EHVRV00, TYPE-CHECKING MISMATCH, PERLOPS_PERLTYPES:\nhashref value expected but undefined/null value found,\ncroaking"
61             );
62             }
63              
64             # if ( UNIVERSAL::isa( $possible_hashref, 'HASH' ) ) { # DEV NOTE: I believe these 2 lines are equivalent?
65 0 0       0 if ( not( main::RPerl_SvHROKp($possible_hashref) ) ) {
66 0         0 croak(
67             "\nERROR EHVRV01, TYPE-CHECKING MISMATCH, PERLOPS_PERLTYPES:\nhashref value expected but non-hashref value found,\ncroaking"
68             );
69             }
70 0         0 return;
71             }
72              
73              
74             sub hashref_CHECKTRACE {
75 0     0   0 { my void $RETURN_TYPE };
  0         0  
76 0         0 ( my $possible_hashref, my $variable_name, my $subroutine_name ) = @ARG;
77 0 0       0 if ( not( defined $possible_hashref ) ) {
78 0         0 croak(
79             "\nERROR EHVRV00, TYPE-CHECKING MISMATCH, PERLOPS_PERLTYPES:\nhashref value expected but undefined/null value found,\nin variable $variable_name from subroutine $subroutine_name,\ncroaking"
80             );
81             }
82 0 0       0 if ( not( main::RPerl_SvHROKp($possible_hashref) ) ) {
83 0         0 croak(
84             "\nERROR EHVRV01, TYPE-CHECKING MISMATCH, PERLOPS_PERLTYPES:\nhashref value expected but non-hashref value found,\nin variable $variable_name from subroutine $subroutine_name,\ncroaking"
85             );
86             }
87 0         0 return;
88             }
89              
90             # [[[ INTEGER HASH REF ]]]
91             # [[[ INTEGER HASH REF ]]]
92             # [[[ INTEGER HASH REF ]]]
93              
94             # (ref to hash) of integers
95             package # hide from PAUSE indexing
96             integer_hashref;
97 7     7   50 use strict;
  7         17  
  7         157  
98 7     7   34 use warnings;
  7         15  
  7         225  
99 7     7   39 use parent -norequire, qw(hashref);
  7         22  
  7         44  
100 7     7   312 use Carp;
  7         19  
  7         480  
101              
102             # [[[ SWITCH CONTEXT BACK TO PRIMARY PACKAGE FOR EXPORT TO WORK ]]]
103             package RPerl::DataStructure::Hash::SubTypes;
104 7     7   46 use strict;
  7         15  
  7         162  
105 7     7   41 use warnings;
  7         13  
  7         5845  
106              
107             # [[[ TYPE-CHECKING ]]]
108              
109             sub integer_hashref_CHECK {
110 0     0   0 { my void $RETURN_TYPE };
  0         0  
111 0         0 ( my $possible_integer_hashref ) = @ARG;
112              
113             # DEV NOTE: the following two if() statements are functionally equivalent to the hashref_CHECK() subroutine, but with integer-specific error codes
114 0 0       0 if ( not( defined $possible_integer_hashref ) ) {
115 0         0 croak(
116             "\nERROR EIVHVRV00, TYPE-CHECKING MISMATCH, PERLOPS_PERLTYPES:\ninteger_hashref value expected but undefined/null value found,\ncroaking"
117             );
118             }
119              
120 0 0       0 if ( not( main::RPerl_SvHROKp($possible_integer_hashref) ) ) {
121 0         0 croak(
122             "\nERROR EIVHVRV01, TYPE-CHECKING MISMATCH, PERLOPS_PERLTYPES:\ninteger_hashref value expected but non-hashref value found,\ncroaking"
123             );
124             }
125              
126 0         0 my integer $possible_integer;
127 0         0 foreach my string $key ( sort keys %{$possible_integer_hashref} ) {
  0         0  
128 0         0 $possible_integer = $possible_integer_hashref->{$key};
129              
130             # DEV NOTE: the following two if() statements are functionally equivalent to the integer_CHECK() subroutine, but with hash-specific error codes
131 0 0       0 if ( not( defined $possible_integer ) ) {
132 0         0 $key =~ s/\\/\\\\/gxms; # escape all back-slash \ characters with another back-slash \ character
133 0         0 $key =~ s/\'/\\\'/gxms; # escape all single-quote ' characters with a back-slash \ character
134 0         0 croak(
135             "\nERROR EIVHVRV02, TYPE-CHECKING MISMATCH, PERLOPS_PERLTYPES:\ninteger_hashref element value expected but undefined/null value found at key '$key',\ncroaking"
136             );
137             }
138 0 0       0 if ( not( main::RPerl_SvIOKp($possible_integer) ) ) {
139 0         0 $key =~ s/\\/\\\\/gxms; # escape all back-slash \ characters with another back-slash \ character
140 0         0 $key =~ s/\'/\\\'/gxms; # escape all single-quote ' characters with a back-slash \ character
141 0         0 croak(
142             "\nERROR EIVHVRV03, TYPE-CHECKING MISMATCH, PERLOPS_PERLTYPES:\ninteger_hashref element value expected but non-integer value found at key '$key',\ncroaking"
143             );
144             }
145             }
146 0         0 return;
147             }
148              
149              
150             sub integer_hashref_CHECKTRACE {
151 19     19   24 { my void $RETURN_TYPE };
  19         28  
152 19         37 ( my $possible_integer_hashref, my $variable_name, my $subroutine_name )
153             = @ARG;
154              
155             # DEV NOTE: the following two if() statements are functionally equivalent to the hashref_CHECKTRACE() subroutine, but with integer-specific error codes
156 19 100       41 if ( not( defined $possible_integer_hashref ) ) {
157 3         43 croak(
158             "\nERROR EIVHVRV00, TYPE-CHECKING MISMATCH, PERLOPS_PERLTYPES:\ninteger_hashref value expected but undefined/null value found,\nin variable $variable_name from subroutine $subroutine_name,\ncroaking"
159             );
160             }
161              
162 16 100       53 if ( not( main::RPerl_SvHROKp($possible_integer_hashref) ) ) {
163 5         52 croak(
164             "\nERROR EIVHVRV01, TYPE-CHECKING MISMATCH, PERLOPS_PERLTYPES:\ninteger_hashref value expected but non-hashref value found,\nin variable $variable_name from subroutine $subroutine_name,\ncroaking"
165             );
166             }
167              
168 11         14 my integer $possible_integer;
169 11         14 foreach my string $key ( sort keys %{$possible_integer_hashref} ) {
  11         57  
170 43         63 $possible_integer = $possible_integer_hashref->{$key};
171              
172             # DEV NOTE: the following two if() statements are functionally equivalent to the integer_CHECKTRACE() subroutine, but with hash-specific error codes
173 43 100       63 if ( not( defined $possible_integer ) ) {
174 2         5 $key =~ s/\\/\\\\/gxms; # escape all back-slash \ characters with another back-slash \ character
175 2         4 $key =~ s/\'/\\\'/gxms; # escape all single-quote ' characters with a back-slash \ character
176 2         26 croak(
177             "\nERROR EIVHVRV02, TYPE-CHECKING MISMATCH, PERLOPS_PERLTYPES:\ninteger_hashref element value expected but undefined/null value found at key '$key',\nin variable $variable_name from subroutine $subroutine_name,\ncroaking"
178             );
179             }
180 41 100       78 if ( not( main::RPerl_SvIOKp($possible_integer) ) ) {
181 5         11 $key =~ s/\\/\\\\/gxms; # escape all back-slash \ characters with another back-slash \ character
182 5         8 $key =~ s/\'/\\\'/gxms; # escape all single-quote ' characters with a back-slash \ character
183 5         56 croak(
184             "\nERROR EIVHVRV03, TYPE-CHECKING MISMATCH, PERLOPS_PERLTYPES:\ninteger_hashref element value expected but non-integer value found at key '$key',\nin variable $variable_name from subroutine $subroutine_name,\ncroaking"
185             );
186             }
187             }
188 4         7 return;
189             }
190              
191             # [[[ STRINGIFY ]]]
192              
193             # convert from (Perl SV containing RV to (Perl HV of (Perl SVs containing IVs))) to Perl-parsable (Perl SV containing PV)
194             sub integer_hashref_to_string {
195 14     14   8789 { my string $RETURN_TYPE };
  14         23  
196 14         20 ( my $input_hv_ref ) = @ARG;
197              
198             # RPerl::diag("in PERLOPS_PERLTYPES integer_hashref_to_string(), top of subroutine\n");
199              
200             # integer_hashref_CHECK($input_hv_ref);
201 14         337 integer_hashref_CHECKTRACE( $input_hv_ref, '$input_hv_ref',
202             'integer_hashref_to_string()' );
203              
204 3         7 my %input_hv;
205              
206             # my integer $input_hv_length;
207             my integer $input_hv_entry_value;
208 3         0 my string $output_sv;
209 3         6 my integer $i_is_0 = 1; # NEED UPGRADE: should be boolean type, not integer
210              
211 3         6 %input_hv = %{$input_hv_ref};
  3         11  
212              
213             # $input_hv_length = scalar keys %input_hv;
214             # RPerl::diag("in PERLOPS_PERLTYPES integer_hashref_to_string(), have \$input_hv_length = $input_hv_length\n");
215              
216 3         7 $output_sv = '{';
217              
218 3         10 foreach my string $key ( sort keys %input_hv ) {
219              
220 15         22 $input_hv_entry_value = $input_hv{$key};
221 15         22 $key =~ s/\\/\\\\/gxms; # escape all back-slash \ characters with another back-slash \ character
222 15         22 $key =~ s/\'/\\\'/gxms; # escape all single-quote ' characters with a back-slash \ character
223              
224             # DEV NOTE: integer type-checking already done as part of integer_hashref_CHECKTRACE()
225             # integer_CHECK($input_hv_entry_value);
226             # integer_CHECKTRACE( $input_hv_entry_value, "\$input_hv_entry_value at key '$key'", 'integer_hashref_to_string()' );
227              
228 15 100       24 if ($i_is_0) { $i_is_0 = 0; }
  3         6  
229 12         16 else { $output_sv .= ', '; }
230             # DEV NOTE: emulate Data::Dumper & follow PBP by using single quotes for key strings
231             # $output_sv .= "'$key' => $input_hv_entry_value"; # NO UNDERSCORES
232 15         39 $output_sv .= "'$key' => " . ::integer_to_string($input_hv_entry_value); # NO UNDERSCORES
233             }
234              
235 3         6 $output_sv .= '}';
236              
237             # RPerl::diag("in PERLOPS_PERLTYPES integer_hashref_to_string(), after for() loop, have \$output_sv =\n$output_sv\n");
238             # RPerl::diag("in PERLOPS_PERLTYPES integer_hashref_to_string(), bottom of subroutine\n");
239 3         19 return ($output_sv);
240             }
241              
242             # [[[ TYPE TESTING ]]]
243              
244             sub integer_hashref__typetest0 {
245 5     5   8 { my string $RETURN_TYPE };
  5         9  
246 5         8 ( my integer_hashref $lucky_integers) = @ARG;
247              
248             # integer_hashref_CHECK($lucky_integers);
249 5         124 integer_hashref_CHECKTRACE( $lucky_integers, '$lucky_integers',
250             'integer_hashref__typetest0()' );
251              
252             # foreach my string $key ( sort keys %{$lucky_integers} ) {
253             # my $lucky_integer = $lucky_integers->{$key};
254             # $key =~ s/\\/\\\\/gxms; # escape all back-slash \ characters with another back-slash \ character
255             # $key =~ s/\'/\\\'/gxms; # escape all single-quote ' characters with a back-slash \ character
256             #
257             # RPerl::diag("in PERLOPS_PERLTYPES integer_hashref__typetest0(), have lucky integer '$key' => " . $lucky_integer . ", BARSTOOL\n");
258             # }
259             # RPerl::diag("in PERLOPS_PERLTYPES integer_hashref__typetest0(), bottom of subroutine\n");
260             return (
261 1         26 integer_hashref_to_string($lucky_integers) . 'PERLOPS_PERLTYPES' );
262             }
263              
264             sub integer_hashref__typetest1 {
265 1     1   3 { my integer_hashref $RETURN_TYPE };
  1         2  
266 1         3 ( my integer $my_size) = @ARG;
267              
268             # integer_CHECK($my_size);
269 1         4 integer_CHECKTRACE( $my_size, '$my_size',
270             'integer_hashref__typetest1()' );
271 1         3 my integer_hashref $new_hash = {};
272 1         2 my string $temp_key;
273 1         4 for my integer $i ( 0 .. ( $my_size - 1 ) ) {
274 5         11 $temp_key = 'PERLOPS_PERLTYPES_funkey' . $i;
275 5         9 $new_hash->{$temp_key} = $i * 5;
276              
277             # RPerl::diag("in PERLOPS_PERLTYPES integer_hashref__typetest1(), setting entry '$temp_key' => " . $new_hash->{$temp_key} . ", BARSTOOL\n");
278             }
279 1         10 return ($new_hash);
280             }
281              
282             # [[[ NUMBER HASH REF ]]]
283             # [[[ NUMBER HASH REF ]]]
284             # [[[ NUMBER HASH REF ]]]
285              
286             # (ref to hash) of numbers
287             package # hide from PAUSE indexing
288             number_hashref;
289 7     7   54 use strict;
  7         21  
  7         151  
290 7     7   35 use warnings;
  7         16  
  7         223  
291 7     7   37 use parent -norequire, qw(hashref);
  7         16  
  7         40  
292 7     7   259 use Carp;
  7         17  
  7         374  
293              
294             # [[[ SWITCH CONTEXT BACK TO PRIMARY PACKAGE FOR EXPORT TO WORK ]]]
295             package RPerl::DataStructure::Hash::SubTypes;
296 7     7   39 use strict;
  7         16  
  7         147  
297 7     7   33 use warnings;
  7         17  
  7         5630  
298              
299             # [[[ TYPE-CHECKING ]]]
300              
301             sub number_hashref_CHECK {
302 0     0   0 { my void $RETURN_TYPE };
  0         0  
303 0         0 ( my $possible_number_hashref ) = @ARG;
304              
305             # DEV NOTE: the following two if() statements are functionally equivalent to the hashref_CHECK() subroutine, but with number-specific error codes
306 0 0       0 if ( not( defined $possible_number_hashref ) ) {
307 0         0 croak(
308             "\nERROR ENVHVRV00, TYPE-CHECKING MISMATCH, PERLOPS_PERLTYPES:\nnumber_hashref value expected but undefined/null value found,\ncroaking"
309             );
310             }
311              
312 0 0       0 if ( not( main::RPerl_SvHROKp($possible_number_hashref) ) ) {
313 0         0 croak(
314             "\nERROR ENVHVRV01, TYPE-CHECKING MISMATCH, PERLOPS_PERLTYPES:\nnumber_hashref value expected but non-hashref value found,\ncroaking"
315             );
316             }
317              
318 0         0 my number $possible_number;
319 0         0 foreach my string $key ( sort keys %{$possible_number_hashref} ) {
  0         0  
320 0         0 $possible_number = $possible_number_hashref->{$key};
321              
322             # DEV NOTE: the following two if() statements are functionally equivalent to the number_CHECK() subroutine, but with hash-specific error codes
323 0 0       0 if ( not( defined $possible_number ) ) {
324 0         0 $key =~ s/\\/\\\\/gxms; # escape all back-slash \ characters with another back-slash \ character
325 0         0 $key =~ s/\'/\\\'/gxms; # escape all single-quote ' characters with a back-slash \ character
326 0         0 croak(
327             "\nERROR ENVHVRV02, TYPE-CHECKING MISMATCH, PERLOPS_PERLTYPES:\nnumber_hashref element value expected but undefined/null value found at key '$key',\ncroaking"
328             );
329             }
330 0 0 0     0 if (not( main::RPerl_SvNOKp($possible_number)
331             || main::RPerl_SvIOKp($possible_number) )
332             )
333             {
334 0         0 $key =~ s/\\/\\\\/gxms; # escape all back-slash \ characters with another back-slash \ character
335 0         0 $key =~ s/\'/\\\'/gxms; # escape all single-quote ' characters with a back-slash \ character
336 0         0 croak(
337             "\nERROR ENVHVRV03, TYPE-CHECKING MISMATCH, PERLOPS_PERLTYPES:\nnumber_hashref element value expected but non-number value found at key '$key',\ncroaking"
338             );
339             }
340             }
341 0         0 return;
342             }
343              
344              
345             sub number_hashref_CHECKTRACE {
346 20     20   26 { my void $RETURN_TYPE };
  20         28  
347 20         38 ( my $possible_number_hashref, my $variable_name, my $subroutine_name )
348             = @ARG;
349              
350             # DEV NOTE: the following two if() statements are functionally equivalent to the hashref_CHECKTRACE() subroutine, but with number-specific error codes
351 20 100       49 if ( not( defined $possible_number_hashref ) ) {
352 3         36 croak(
353             "\nERROR ENVHVRV00, TYPE-CHECKING MISMATCH, PERLOPS_PERLTYPES:\nnumber_hashref value expected but undefined/null value found,\nin variable $variable_name from subroutine $subroutine_name,\ncroaking"
354             );
355             }
356              
357 17 100       46 if ( not( main::RPerl_SvHROKp($possible_number_hashref) ) ) {
358 5         54 croak(
359             "\nERROR ENVHVRV01, TYPE-CHECKING MISMATCH, PERLOPS_PERLTYPES:\nnumber_hashref value expected but non-hashref value found,\nin variable $variable_name from subroutine $subroutine_name,\ncroaking"
360             );
361             }
362              
363 12         18 my number $possible_number;
364 12         16 foreach my string $key ( sort keys %{$possible_number_hashref} ) {
  12         62  
365 47         66 $possible_number = $possible_number_hashref->{$key};
366              
367             # DEV NOTE: the following two if() statements are functionally equivalent to the number_CHECKTRACE() subroutine, but with hash-specific error codes
368 47 100       90 if ( not( defined $possible_number ) ) {
369 2         5 $key =~ s/\\/\\\\/gxms; # escape all back-slash \ characters with another back-slash \ character
370 2         5 $key =~ s/\'/\\\'/gxms; # escape all single-quote ' characters with a back-slash \ character
371 2         32 croak(
372             "\nERROR ENVHVRV02, TYPE-CHECKING MISMATCH, PERLOPS_PERLTYPES:\nnumber_hashref element value expected but undefined/null value found at key '$key',\nin variable $variable_name from subroutine $subroutine_name,\ncroaking"
373             );
374             }
375 45 100 100     125 if (not( main::RPerl_SvNOKp($possible_number)
376             || main::RPerl_SvIOKp($possible_number) )
377             )
378             {
379 4         9 $key =~ s/\\/\\\\/gxms; # escape all back-slash \ characters with another back-slash \ character
380 4         11 $key =~ s/\'/\\\'/gxms; # escape all single-quote ' characters with a back-slash \ character
381 4         46 croak(
382             "\nERROR ENVHVRV03, TYPE-CHECKING MISMATCH, PERLOPS_PERLTYPES:\nnumber_hashref element value expected but non-number value found at key '$key',\nin variable $variable_name from subroutine $subroutine_name,\ncroaking"
383             );
384             }
385             }
386 6         14 return;
387             }
388              
389             # [[[ STRINGIFY ]]]
390              
391             # convert from (Perl SV containing RV to (Perl HV of (Perl SVs containing NVs))) to Perl-parsable (Perl SV containing PV)
392             sub number_hashref_to_string {
393 15     15   9397 { my string $RETURN_TYPE };
  15         28  
394 15         22 ( my $input_hv_ref ) = @ARG;
395              
396             # RPerl::diag("in PERLOPS_PERLTYPES number_hashref_to_string(), top of subroutine\n");
397              
398             # number_hashref_CHECK($input_hv_ref);
399 15         351 number_hashref_CHECKTRACE( $input_hv_ref, '$input_hv_ref',
400             'number_hashref_to_string()' );
401              
402 5         12 my %input_hv;
403              
404             # my integer $input_hv_length;
405             my number $input_hv_entry_value;
406 5         0 my string $output_sv;
407 5         7 my integer $i_is_0 = 1; # NEED UPGRADE: should be boolean type, not integer
408              
409 5         8 %input_hv = %{$input_hv_ref};
  5         18  
410              
411             # $input_hv_length = scalar keys %input_hv;
412             # RPerl::diag("in PERLOPS_PERLTYPES number_hashref_to_string(), have \$input_hv_length = $input_hv_length\n");
413              
414 5         8 $output_sv = '{';
415              
416 5         16 foreach my string $key ( sort keys %input_hv ) {
417              
418 23         39 $input_hv_entry_value = $input_hv{$key};
419 23         35 $key =~ s/\\/\\\\/gxms; # escape all back-slash \ characters with another back-slash \ character
420 23         34 $key =~ s/\'/\\\'/gxms; # escape all single-quote ' characters with a back-slash \ character
421              
422 23 100       34 if ($i_is_0) { $i_is_0 = 0; }
  5         8  
423 18         23 else { $output_sv .= ', '; }
424             # $output_sv .= "'$key' => $input_hv_entry_value";
425 23         423 $output_sv .= q{'} . $key . q{' => } . RPerl::DataType::Number::number_to_string($input_hv_entry_value);
426             }
427              
428 5         12 $output_sv .= '}';
429              
430             # RPerl::diag("in PERLOPS_PERLTYPES number_hashref_to_string(), after for() loop, have \$output_sv =\n$output_sv\n");
431             # RPerl::diag("in PERLOPS_PERLTYPES number_hashref_to_string(), bottom of subroutine\n");
432 5         31 return ($output_sv);
433             }
434              
435             # [[[ TYPE TESTING ]]]
436              
437             sub number_hashref__typetest0 {
438 5     5   10 { my string $RETURN_TYPE };
  5         7  
439 5         12 ( my number_hashref $lucky_numbers) = @ARG;
440              
441             # number_hashref_CHECK($lucky_numbers);
442 5         125 number_hashref_CHECKTRACE( $lucky_numbers, '$lucky_numbers',
443             'number_hashref__typetest0()' );
444              
445             # foreach my string $key ( sort keys %{$lucky_numbers} ) {
446             # my $lucky_number = $lucky_numbers->{$key};
447             # $key =~ s/\\/\\\\/gxms; # escape all back-slash \ characters with another back-slash \ character
448             # $key =~ s/\'/\\\'/gxms; # escape all single-quote ' characters with a back-slash \ character
449             # RPerl::diag("in PERLOPS_PERLTYPES number_hashref__typetest0(), have lucky number '$key' => " . $lucky_number . ", BARSTOOL\n");
450             # }
451             return (
452 1         24 number_hashref_to_string($lucky_numbers) . 'PERLOPS_PERLTYPES' );
453             }
454              
455             sub number_hashref__typetest1 {
456 1     1   3 { my number_hashref $RETURN_TYPE };
  1         2  
457 1         3 ( my integer $my_size) = @ARG;
458              
459             # integer_CHECK($my_size);
460 1         7 integer_CHECKTRACE( $my_size, '$my_size',
461             'number_hashref__typetest1()' );
462 1         2 my number_hashref $new_hash = {};
463 1         3 my string $temp_key;
464 1         5 for my integer $i ( 0 .. ( $my_size - 1 ) ) {
465 5         8 $temp_key = 'PERLOPS_PERLTYPES_funkey' . $i;
466 5         14 $new_hash->{$temp_key} = $i * 5.123456789;
467              
468             # RPerl::diag("in PERLOPS_PERLTYPES number_hashref__typetest1(), setting entry '$temp_key' => " . $new_hash->{$temp_key} . ", BARSTOOL\n");
469             }
470 1         5 return ($new_hash);
471             }
472              
473             # [[[ CHARACTER HASHE REF ]]]
474             # [[[ CHARACTER HASHE REF ]]]
475             # [[[ CHARACTER HASHE REF ]]]
476              
477             # (ref to hash) of chars
478             package # hide from PAUSE indexing
479             character_hashref;
480 7     7   50 use strict;
  7         17  
  7         151  
481 7     7   36 use warnings;
  7         13  
  7         235  
482 7     7   37 use parent -norequire, qw(hashref);
  7         13  
  7         34  
483              
484             # [[[ STRING HASH REF ]]]
485             # [[[ STRING HASH REF ]]]
486             # [[[ STRING HASH REF ]]]
487              
488             # (ref to hash) of strings
489             package # hide from PAUSE indexing
490             string_hashref;
491 7     7   318 use strict;
  7         14  
  7         132  
492 7     7   33 use warnings;
  7         18  
  7         213  
493 7     7   35 use parent -norequire, qw(hashref);
  7         18  
  7         33  
494 7     7   257 use Carp;
  7         22  
  7         366  
495              
496             # [[[ SWITCH CONTEXT BACK TO PRIMARY PACKAGE FOR EXPORT TO WORK ]]]
497             package RPerl::DataStructure::Hash::SubTypes;
498 7     7   44 use strict;
  7         15  
  7         129  
499 7     7   32 use warnings;
  7         15  
  7         5642  
500              
501             # [[[ TYPE-CHECKING ]]]
502              
503             sub string_hashref_CHECK {
504 0     0   0 { my void $RETURN_TYPE };
  0         0  
505 0         0 ( my $possible_string_hashref ) = @ARG;
506              
507             # DEV NOTE: the following two if() statements are functionally equivalent to the hashref_CHECK() subroutine, but with string-specific error codes
508 0 0       0 if ( not( defined $possible_string_hashref ) ) {
509 0         0 croak(
510             "\nERROR EPVHVRV00, TYPE-CHECKING MISMATCH, PERLOPS_PERLTYPES:\nstring_hashref value expected but undefined/null value found,\ncroaking"
511             );
512             }
513              
514 0 0       0 if ( not( main::RPerl_SvHROKp($possible_string_hashref) ) ) {
515 0         0 croak(
516             "\nERROR EPVHVRV01, TYPE-CHECKING MISMATCH, PERLOPS_PERLTYPES:\nstring_hashref value expected but non-hashref value found,\ncroaking"
517             );
518             }
519              
520 0         0 my string $possible_string;
521 0         0 foreach my string $key ( sort keys %{$possible_string_hashref} ) {
  0         0  
522 0         0 $possible_string = $possible_string_hashref->{$key};
523              
524             # DEV NOTE: the following two if() statements are functionally equivalent to the string_CHECK() subroutine, but with hash-specific error codes
525 0 0       0 if ( not( defined $possible_string ) ) {
526 0         0 $key =~ s/\\/\\\\/gxms; # escape all back-slash \ characters with another back-slash \ character
527 0         0 $key =~ s/\'/\\\'/gxms; # escape all single-quote ' characters with a back-slash \ character
528 0         0 croak(
529             "\nERROR EPVHVRV02, TYPE-CHECKING MISMATCH, PERLOPS_PERLTYPES:\nstring_hashref element value expected but undefined/null value found at key '$key',\ncroaking"
530             );
531             }
532 0 0       0 if ( not( main::RPerl_SvPOKp($possible_string) ) ) {
533 0         0 $key =~ s/\\/\\\\/gxms; # escape all back-slash \ characters with another back-slash \ character
534 0         0 $key =~ s/\'/\\\'/gxms; # escape all single-quote ' characters with a back-slash \ character
535 0         0 croak(
536             "\nERROR EPVHVRV03, TYPE-CHECKING MISMATCH, PERLOPS_PERLTYPES:\nstring_hashref element value expected but non-string value found at key '$key',\ncroaking"
537             );
538             }
539             }
540 0         0 return;
541             }
542              
543              
544             sub string_hashref_CHECKTRACE {
545 23     23   30 { my void $RETURN_TYPE };
  23         39  
546 23         46 ( my $possible_string_hashref, my $variable_name, my $subroutine_name )
547             = @ARG;
548              
549             # DEV NOTE: the following two if() statements are functionally equivalent to the hashref_CHECKTRACE() subroutine, but with string-specific error codes
550 23 100       57 if ( not( defined $possible_string_hashref ) ) {
551 3         41 croak(
552             "\nERROR EPVHVRV00, TYPE-CHECKING MISMATCH, PERLOPS_PERLTYPES:\nstring_hashref value expected but undefined/null value found,\nin variable $variable_name from subroutine $subroutine_name,\ncroaking"
553             );
554             }
555              
556 20 100       58 if ( not( main::RPerl_SvHROKp($possible_string_hashref) ) ) {
557 5         53 croak(
558             "\nERROR EPVHVRV01, TYPE-CHECKING MISMATCH, PERLOPS_PERLTYPES:\nstring_hashref value expected but non-hashref value found,\nin variable $variable_name from subroutine $subroutine_name,\ncroaking"
559             );
560             }
561              
562 15         23 my string $possible_string;
563 15         24 foreach my string $key ( sort keys %{$possible_string_hashref} ) {
  15         77  
564 36         63 $possible_string = $possible_string_hashref->{$key};
565              
566             # DEV NOTE: the following two if() statements are functionally equivalent to the string_CHECKTRACE() subroutine, but with hash-specific error codes
567 36 100       58 if ( not( defined $possible_string ) ) {
568 2         6 $key =~ s/\\/\\\\/gxms; # escape all back-slash \ characters with another back-slash \ character
569 2         3 $key =~ s/\'/\\\'/gxms; # escape all single-quote ' characters with a back-slash \ character
570 2         25 croak(
571             "\nERROR EPVHVRV02, TYPE-CHECKING MISMATCH, PERLOPS_PERLTYPES:\nstring_hashref element value expected but undefined/null value found at key '$key',\nin variable $variable_name from subroutine $subroutine_name,\ncroaking"
572             );
573             }
574 34 100       88 if ( not( main::RPerl_SvPOKp($possible_string) ) ) {
575 5         9 $key =~ s/\\/\\\\/gxms; # escape all back-slash \ characters with another back-slash \ character
576 5         9 $key =~ s/\'/\\\'/gxms; # escape all single-quote ' characters with a back-slash \ character
577 5         56 croak(
578             "\nERROR EPVHVRV03, TYPE-CHECKING MISMATCH, PERLOPS_PERLTYPES:\nstring_hashref element value expected but non-string value found at key '$key',\nin variable $variable_name from subroutine $subroutine_name,\ncroaking"
579             );
580             }
581             }
582 8         20 return;
583             }
584              
585             # [[[ STRINGIFY ]]]
586              
587             # convert from (Perl SV containing RV to (Perl HV of (Perl SVs containing PVs))) to Perl-parsable (Perl SV containing PV)
588             sub string_hashref_to_string {
589 18     18   14916 { my string $RETURN_TYPE };
  18         34  
590 18         30 ( my $input_hv_ref ) = @ARG;
591              
592             # RPerl::diag("in PERLOPS_PERLTYPES string_hashref_to_string(), top of subroutine\n");
593              
594             # string_hashref_CHECK($input_hv_ref);
595 18         468 string_hashref_CHECKTRACE( $input_hv_ref, '$input_hv_ref',
596             'string_hashref_to_string()' );
597              
598 7         17 my %input_hv;
599              
600             # my integer $input_hv_length;
601             my string $input_hv_entry_value;
602 7         0 my string $output_sv;
603 7         11 my integer $i_is_0 = 1; # NEED UPGRADE: should be boolean type, not integer
604              
605 7         10 %input_hv = %{$input_hv_ref};
  7         27  
606              
607             # $input_hv_length = scalar keys %input_hv;
608             # RPerl::diag("in PERLOPS_PERLTYPES string_hashref_to_string(), have \$input_hv_length = $input_hv_length\n");
609              
610 7         13 $output_sv = '{';
611              
612 7         23 foreach my string $key ( sort keys %input_hv ) {
613              
614 26         38 $input_hv_entry_value = $input_hv{$key};
615 26         42 $key =~ s/\\/\\\\/gxms; # escape all back-slash \ characters with another back-slash \ character
616 26         37 $key =~ s/\'/\\\'/gxms; # escape all single-quote ' characters with a back-slash \ character
617              
618 26 100       43 if ($i_is_0) { $i_is_0 = 0; }
  7         11  
619 19         23 else { $output_sv .= ', '; }
620 26         34 $input_hv_entry_value =~ s/\\/\\\\/gxms; # escape all back-slash \ characters with another back-slash \ character
621 26         36 $input_hv_entry_value =~ s/\'/\\\'/gxms; # escape all single-quote ' characters with a back-slash \ character
622 26         64 $output_sv .= "'$key' => '$input_hv_entry_value'";
623             }
624              
625 7         17 $output_sv .= '}';
626              
627             # RPerl::diag("in PERLOPS_PERLTYPES string_hashref_to_string(), after for() loop, have \$output_sv =\n$output_sv\n");
628             # RPerl::diag("in PERLOPS_PERLTYPES string_hashref_to_string(), bottom of subroutine\n");
629 7         39 return ($output_sv);
630             }
631              
632             # [[[ TYPE TESTING ]]]
633              
634             sub string_hashref__typetest0 {
635 5     5   9 { my string $RETURN_TYPE };
  5         10  
636 5         11 ( my string_hashref $people) = @ARG;
637              
638             # string_hashref_CHECK($lucky_numbers);
639 5         134 string_hashref_CHECKTRACE( $people, '$people',
640             'string_hashref__typetest0()' );
641              
642             # foreach my string $key ( sort keys %{$people} ) {
643             # my $person = $people->{$key};
644             # $key =~ s/\\/\\\\/gxms; # escape all back-slash \ characters with another back-slash \ character
645             # $key =~ s/\'/\\\'/gxms; # escape all single-quote ' characters with a back-slash \ character
646             # RPerl::diag("in PERLOPS_PERLTYPES string_hashref__typetest0(), have person '$key' => '" . $person . "', STARBOOL\n");
647             # }
648 1         34 return ( string_hashref_to_string($people) . 'PERLOPS_PERLTYPES' );
649             }
650              
651             sub string_hashref__typetest1 {
652 1     1   2 { my string_hashref $RETURN_TYPE };
  1         2  
653 1         3 ( my integer $my_size) = @ARG;
654              
655             # integer_CHECK($my_size);
656 1         6 integer_CHECKTRACE( $my_size, '$my_size',
657             'string_hashref__typetest1()' );
658 1         2 my string_hashref $people = {};
659 1         5 for my integer $i ( 0 .. ( $my_size - 1 ) ) {
660 5         16 $people->{ 'PERLOPS_PERLTYPES_Luker_key' . $i }
661             = q{Jeffy Ten! } . $i . q{/} . ( $my_size - 1 );
662              
663             # RPerl::diag("in PERLOPS_PERLTYPES string_hashref__typetest1(), bottom of for() loop, have i = $i, just set another Jeffy!\n");
664             }
665 1         11 return ($people);
666             }
667              
668             # [[[ SCALAR HASHES ]]]
669              
670             # (ref to hash) of scalartypes
671             package # hide from PAUSE indexing
672             scalartype_hashref;
673 7     7   55 use strict;
  7         16  
  7         172  
674 7     7   38 use warnings;
  7         15  
  7         234  
675 7     7   37 use parent -norequire, qw(hashref);
  7         15  
  7         34  
676              
677             # [[[ ARRAY HASHES (2-dimensional) ]]]
678              
679             # (ref to hash) of (refs to arrays)
680             package # hide from PAUSE indexing
681             arrayref_hashref;
682 7     7   341 use strict;
  7         16  
  7         131  
683 7     7   33 use warnings;
  7         19  
  7         214  
684 7     7   37 use parent -norequire, qw(hashref);
  7         16  
  7         32  
685              
686             # [[[ HASH HASHES (2-dimesional) ]]]
687              
688             # (ref to hash) of (refs to hashs)
689             package # hide from PAUSE indexing
690             hashref_hashref;
691 7     7   312 use strict;
  7         16  
  7         127  
692 7     7   34 use warnings;
  7         16  
  7         197  
693 7     7   37 use parent -norequire, qw(hashref);
  7         16  
  7         29  
694              
695             # [ HOMOGENEOUS HASH HASHES (2-dimensional) ]
696              
697             # (ref to hash) of (refs to (hashs of integers))
698             package # hide from PAUSE indexing
699             integer_hashref_hashref;
700 7     7   331 use strict;
  7         17  
  7         127  
701 7     7   37 use warnings;
  7         15  
  7         186  
702 7     7   38 use parent -norequire, qw(hashref_hashref);
  7         18  
  7         36  
703              
704             # (ref to hash) of (refs to (hashs of numbers))
705             package # hide from PAUSE indexing
706             number_hashref_hashref;
707 7     7   347 use strict;
  7         17  
  7         179  
708 7     7   38 use warnings;
  7         15  
  7         211  
709 7     7   38 use parent -norequire, qw(hashref_hashref);
  7         12  
  7         32  
710              
711             # (ref to hash) of (refs to (hashs of strings))
712             package # hide from PAUSE indexing
713             string_hashref_hashref;
714 7     7   351 use strict;
  7         21  
  7         149  
715 7     7   38 use warnings;
  7         18  
  7         230  
716 7     7   40 use parent -norequire, qw(hashref_hashref);
  7         16  
  7         31  
717              
718             # (ref to hash) of (refs to (hashs of scalars))
719             package # hide from PAUSE indexing
720             scalartype_hashref_hashref;
721 7     7   349 use strict;
  7         19  
  7         147  
722 7     7   34 use warnings;
  7         16  
  7         211  
723 7     7   34 use parent -norequire, qw(hashref_hashref);
  7         14  
  7         29  
724              
725             # [[[ OBJECT HASHES (2-dimensional) ]]]
726              
727             # (ref to hash) of objects
728             package # hide from PAUSE indexing
729             object_hashref;
730 7     7   312 use strict;
  7         15  
  7         129  
731 7     7   35 use warnings;
  7         18  
  7         190  
732 7     7   37 use parent -norequire, qw(hashref);
  7         14  
  7         32  
733              
734             1; # end of package