File Coverage

blib/lib/RPerl/DataStructure/Hash/SubTypes.pm
Criterion Covered Total %
statement 228 289 78.8
branch 24 56 42.8
condition 3 6 50.0
subroutine 62 67 92.5
pod 0 8 0.0
total 317 426 74.4


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