File Coverage

blib/lib/RPerl/Exporter.pm
Criterion Covered Total %
statement 170 770 22.0
branch 55 246 22.3
condition 20 60 33.3
subroutine 15 279 5.3
pod n/a
total 260 1355 19.1


line stmt bran cond sub pod time code
1             # [[[ HEADER ]]]
2             package RPerl::Exporter;
3 7     7   41 use strict;
  7         13  
  7         174  
4 7     7   33 use warnings;
  7         11  
  7         140  
5 7     7   29 use RPerl::Config;
  7         10  
  7         924  
6             our $VERSION = 0.005_000;
7              
8             # [[[ OO INHERITANCE ]]]
9             #use parent qw(RPerl::CompileUnit::Module::Class);
10             #use RPerl::CompileUnit::Module::Class;
11              
12             # [[[ EXPORTS ]]]
13             #use RPerl::Exporter qw(import); # hey that's me!
14             #our @EXPORT_OK = qw(import); # so meta ;-)
15              
16             # [[[ CRITICS ]]]
17             ## no critic qw(ProhibitUselessNoCritic ProhibitMagicNumbers RequireCheckedSyscalls) # USER DEFAULT 1: allow numeric values & print operator
18             ## no critic qw(RequireInterpolationOfMetachars) # USER DEFAULT 2: allow single-quoted control characters & sigils
19              
20             # [[[ INCLUDES ]]]
21 7     7   44 use rperltypes;
  7         16  
  7         474  
22              
23             # [[[ OO PROPERTIES ]]]
24             #our hashref $properties = {};
25              
26             # DEV NOTE, CORRELATION #rp051: hard-coded list of RPerl data types and data structures
27             # NOT MISSING: boolean, unsigned_integer, character
28             # MISSING: *_arrayref, *_hashref
29             #our string_arrayref $SUPPORTED = [
30             our $SUPPORTED_ALL = [
31             qw(
32             void
33             boolean
34             unsigned_integer
35             integer
36             number
37             character
38             string
39             integer_arrayref
40             number_arrayref
41             string_arrayref
42             integer_hashref
43             number_hashref
44             string_hashref
45             )
46             ];
47             #our string_arrayref $SUPPORTED_SPECIAL = [
48             our $SUPPORTED_SPECIAL = [
49             qw(
50             sse_number_pair
51             gmp_integer
52             gsl_matrix
53             )
54             ];
55              
56             # [[[ SUBROUTINES & OO METHODS ]]]
57              
58             sub import {
59 7     7   38 no strict;
  7         12  
  7         3487  
60 598     598   126748 my $package_exporter = shift @ARG; # variable number of args, must use shift
61 598         1248 my $package_importer = caller(0);
62              
63             # USAGE OPTION A, OPTIONAL @EXPORT_OK, NON-INHERITED, EXPORTER;
64             # package Foo;
65             # use RPerl::Exporter qw(import);
66             # our @EXPORT_OK = (howdy);
67             # USAGE OPTION A, OPTIONAL @EXPORT_OK, NON-INHERITED, IMPORTER;
68             # use Foo qw(howdy); # importer must request howdy()
69             # howdy();
70              
71             # USAGE OPTION B, OPTIONAL @EXPORT_OK, INHERITED, EXPORTER; NEED UPGRADE: REQUIRES MULTIPLE INHERITANCE, WILL NOT CURRENTLY PARSE
72             # package Foo;
73             # use parent qw(... RPerl::Exporter ...); # or set @ISA directly, etc.
74             # use RPerl::Exporter;
75             # our @EXPORT_OK = (howdy);
76             # USAGE OPTION B, OPTIONAL @EXPORT_OK, INHERITED, IMPORTER;
77             # use Foo qw(howdy); # importer must request howdy()
78             # howdy();
79              
80             # USAGE OPTION C, FORCED @EXPORT , NON-INHERITED, EXPORTER;
81             # package Foo;
82             # use RPerl::Exporter qw(import);
83             # our @EXPORT = (howdy);
84             # USAGE OPTION C, FORCED @EXPORT , NON-INHERITED, IMPORTER;
85             # use Foo; # importer may optionally request howdy(), or other subroutines
86             # howdy();
87              
88             # USAGE OPTION D, FORCED @EXPORT , INHERITED, EXPORTER; NEED UPGRADE: REQUIRES MULTIPLE INHERITANCE, WILL NOT CURRENTLY PARSE
89             # package Foo;
90             # use parent qw(... RPerl::Exporter ...); # or set @ISA directly, etc.
91             # use RPerl::Exporter;
92             # our @EXPORT = (howdy);
93             # USAGE OPTION D, FORCED @EXPORT , INHERITED, IMPORTER;
94             # use Foo; # importer may optionally request howdy(), or other subroutines
95             # howdy();
96              
97             # RPerl::diag(q{in Exporter::import(), have $package_exporter = '}, $package_exporter, q{'}, "\n");
98             # RPerl::diag(q{in Exporter::import(), have @{$package_exporter . '::EXPORT'} = }, Dumper(\@{$package_exporter . '::EXPORT'}), "\n");
99              
100             # there are still arguments remaining to be received
101 598 100       1586 if (scalar @ARG) {
102             # USAGE OPTIONS A & C ONLY: give non-inherited access to import()
103             # RPerl::diag(q{in Exporter::import(), have @ARG = }, Dumper(\@ARG), "\n");
104 104 100       540 if ($package_exporter eq 'RPerl::Exporter') {
105 93 50       236 if ($ARG[0] eq 'import') {
106             # this is RPerl::Exporter::import() explicitly exporting itself into the importing package's namespace as import()
107 93         298 *{$package_importer . '::import'} = \&import; # short form, symbol table direct, not strict
  93         583  
108 93         31494 return;
109             }
110             else {
111 0         0 croak 'ERROR ESUXP00, Subroutine Exporter: Failed to give inheritance of subroutine ' . $ARG[0] . q{(), only the import() subroutine is available to be inherited from package RPerl::Exporter, croaking};
112             }
113             }
114             # USAGE OPTIONS A & B REQUIRED, C & D OPTIONAL: receive requests for subroutines to be exported
115             else {
116 11         30 my $subroutines_export = {};
117 11         31 my $subroutines_export_ok = {};
118 11         23 my $variables_export = {};
119 11         26 my $variables_export_ok = {};
120            
121             # populate quick-lookup hash tables from @EXPORT & @EXPORT_OK
122 11         25 foreach my $subroutine_or_variable_export (@{$package_exporter . '::EXPORT'}) {
  11         57  
123 60         92 my $possible_sigil = substr $subroutine_or_variable_export, 0, 1;
124 60 50 33     274 if (($possible_sigil eq '$') or
      33        
      33        
125             ($possible_sigil eq '@') or
126             ($possible_sigil eq '%') or
127             ($possible_sigil eq '*')) {
128 0         0 $variables_export->{$subroutine_or_variable_export} = 1;
129             }
130             else {
131 60 50       164 if ($possible_sigil eq '&') {
    50          
132             # drop unnecessary ampersand sigils
133 0         0 substr $subroutine_or_variable_export, 0, 1, q{};
134             }
135             elsif ($possible_sigil !~ /\w/) {
136 0         0 croak q{ERROR ESYXP00, Subroutine & Variable Exporter: Failed to process @EXPORT symbol '} . $subroutine_or_variable_export . q{' from package '} . $package_exporter . q{', symbol begins with unrecognized character '}, $possible_sigil, q{', croaking};
137             }
138 60         126 $subroutines_export->{$subroutine_or_variable_export} = 1;
139             }
140             }
141 11         25 foreach my $subroutine_or_variable_export_ok (@{$package_exporter . '::EXPORT_OK'}) {
  11         54  
142 29         64 my $possible_sigil = substr $subroutine_or_variable_export_ok, 0, 1;
143             # RPerl::diag(q{in Exporter::import(), have $possible_sigil = '}, $possible_sigil, q{'}, "\n");
144 29 50 33     216 if (($possible_sigil eq '$') or
      33        
      33        
145             ($possible_sigil eq '@') or
146             ($possible_sigil eq '%') or
147             ($possible_sigil eq '*')) {
148 0         0 $variables_export_ok->{$subroutine_or_variable_export_ok} = 1;
149             }
150             else {
151 29 50       115 if ($possible_sigil eq '&') {
    50          
152             # drop unnecessary ampersand sigils
153 0         0 substr $subroutine_or_variable_export_ok, 0, 1, q{};
154             }
155             elsif ($possible_sigil !~ /\w/) {
156 0         0 croak q{ERROR ESYXP01, Subroutine & Variable Exporter: Failed to process @EXPORT_OK symbol '} . $subroutine_or_variable_export_ok . q{' from package '} . $package_exporter . q{', symbol begins with unrecognized character '}, $possible_sigil, q{', croaking};
157             }
158 29         80 $subroutines_export_ok->{$subroutine_or_variable_export_ok} = 1;
159             }
160             }
161              
162             # process all requested subroutines & variables
163 11         29 foreach my $subroutine_or_variable (@ARG) {
164 27         67 my $possible_sigil = substr $subroutine_or_variable, 0, 1;
165             # RPerl::diag(q{in Exporter::import(), have requested $subroutine_or_variable = '}, $subroutine_or_variable, q{'}, "\n"); # DEV NOTE: causes false errors in t/12_parse.t???
166             # RPerl::diag(q{in Exporter::import(), have $possible_sigil = '}, $possible_sigil, q{'}, "\n"); # DEV NOTE: causes false errors in t/12_parse.t???
167 27 50 33     293 if (($possible_sigil eq '$') or
      33        
      33        
168             ($possible_sigil eq '@') or
169             ($possible_sigil eq '%') or
170             ($possible_sigil eq '*')) {
171 0         0 my $variable = $subroutine_or_variable;
172 0         0 my $variable_no_sigil = substr $variable, 1;
173              
174 0 0       0 if (not defined *{ $package_exporter . '::' . $variable_no_sigil }) {
  0         0  
175 0         0 croak q{ERROR EVAXP00, Variable Exporter: Failed to export requested variable '} . $variable . q{' from package '} . $package_exporter . q{' into requesting package '} . $package_importer . q{', variable does not exist, croaking};
176             }
177             # requested variable is already in @EXPORT, skip it
178 0 0       0 if (exists $variables_export->{$variable}) {
    0          
179 0         0 RPerl::warning(q{WARNING WVAXP00, Variable Exporter: Redundant request to export variable '} . $variable . q{' from package '} . $package_exporter . q{' into requesting package '} . $package_importer . q{', variable already exists in exporting package's @EXPORT} . "\n");
180 0         0 next;
181             }
182             # requested variable is in @EXPORT_OK, export it
183             elsif (exists $variables_export_ok->{$variable}) {
184 7     7   53 no strict;
  7         13  
  7         2361  
185             # define actual exported variable
186             # DEV NOTE: can not test for pre-existing variables because there is no valid defined(@array), etc.
187 0 0       0 if ($possible_sigil eq '$') { # SCALAR
    0          
    0          
    0          
188 0         0 *{ $package_importer . '::' . $variable_no_sigil } = \${ $package_exporter . '::' . $variable_no_sigil };
  0         0  
  0         0  
189             }
190             elsif ($possible_sigil eq '@') { # ARRAY
191 0         0 *{ $package_importer . '::' . $variable_no_sigil } = \@{ $package_exporter . '::' . $variable_no_sigil };
  0         0  
  0         0  
192             }
193             elsif ($possible_sigil eq '%') { # HASH
194 0         0 *{ $package_importer . '::' . $variable_no_sigil } = \%{ $package_exporter . '::' . $variable_no_sigil };
  0         0  
  0         0  
195             }
196             elsif ($possible_sigil eq '*') { # TYPEGLOB
197 0         0 *{ $package_importer . '::' . $variable_no_sigil } = *{ $package_exporter . '::' . $variable_no_sigil };
  0         0  
  0         0  
198             }
199             }
200             # requested variable is not in @EXPORT or @EXPORT_OK, error
201             else {
202 0         0 croak q{ERROR EVAXP01, Variable Exporter: Failed to export requested variable '} . $variable . q{' from package '} . $package_exporter . q{' into requesting package '} . $package_importer . q{', variable not found in exporting package's @EXPORT or @EXPORT_OK, croaking};
203             }
204             }
205             else {
206 27         43 my $subroutine = $subroutine_or_variable;
207              
208 27 50       118 if ($possible_sigil eq '&') {
    50          
209             # drop unnecessary ampersand sigils
210 0         0 substr $subroutine, 0, 1, q{};
211             }
212             elsif ($possible_sigil !~ /\w/) {
213 0         0 croak q{ERROR ESYXP02, Subroutine & Variable Exporter: Failed to export symbol '} . $subroutine_or_variable . q{' from package '} . $package_exporter . q{' into requesting package '} . $package_importer . q{', symbol begins with unrecognized character '}, $possible_sigil, q{', croaking};
214             }
215              
216 27 50       40 if (not defined *{ $package_exporter . '::' . $subroutine }) {
  27         123  
217 0         0 croak q{ERROR ESUXP01, Subroutine Exporter: Failed to export requested subroutine '} . $subroutine . q{()' from package '} . $package_exporter . q{' into requesting package '} . $package_importer . q{', subroutine does not exist, croaking};
218             }
219             # requested subroutine is already in @EXPORT, skip it
220 27 50       85 if (exists $subroutines_export->{$subroutine}) {
    50          
221 0         0 RPerl::warning(q{WARNING WSUXP00, Subroutine Exporter: Redundant request to export subroutine '} . $subroutine . q{()' from package '} . $package_exporter . q{' into requesting package '} . $package_importer . q{', subroutine already exists in exporting package's @EXPORT} . "\n");
222 0         0 next;
223             }
224             # requested subroutine is in @EXPORT_OK, export it
225             elsif (exists $subroutines_export_ok->{$subroutine}) {
226             # enable args type-checking except for exempted subs below
227 27         39 my $args_type_checking = 1;
228            
229             # type-checking subs
230 27 50 33     204 if (($subroutine =~ m/_CHECK$/) or
    50 33        
      33        
      0        
231             ($subroutine =~ m/_CHECKTRACE$/)) {
232 0         0 $args_type_checking = 0;
233             }
234             # non-RPerl subs
235             # DEV NOTE, CORRELATION #rp051: hard-coded list of non-RPerl subroutines
236             # DEV NOTE, CORRELATION #rp052: gsl_matrix_to_*() and gsl_matrix_rows() and gsl_matrix_cols() are RPerl subroutines
237             elsif (($subroutine =~ m/^gsl_/) and
238             ($subroutine !~ m/^gsl_matrix_to/) and
239             ($subroutine ne 'gsl_matrix_rows') and
240             ($subroutine ne 'gsl_matrix_cols')) {
241 0         0 $args_type_checking = 0;
242             }
243            
244             =DISABLED_NO_ARGS
245             # DEV NOTE, CORRELATION #rp053: even with the upgrade to normal Perl subroutine headers, we must still activate subroutines w/out args or when type-checking is explicitly disabled with CHECK OFF, in order for RPerl::Exporter to work properly, presumably because Exporter.pm runs before Class.pm and thus we can not test for the existence of __CHECKED_*() subroutines in RPerl::Exporter::import()
246             # subs with no args (and thus no arg type-checking)
247             elsif (not defined *{ $package_exporter . '::__CHECK_CODE_' . $subroutine }) {
248             $args_type_checking = 0;
249             }
250             =cut
251            
252             # RPerl::diag('in Exporter::import(), have $SUPPORTED_ALL etc = ' . Dumper([@{$SUPPORTED_ALL}, @{$SUPPORTED_SPECIAL}]) . "\n");
253            
254             # type-conversion subs
255 27         44 foreach my $rperl_type (sort @{[@{$SUPPORTED_ALL}, @{$SUPPORTED_SPECIAL}]}) {
  27         35  
  27         53  
  27         218  
256 432         531 my $subroutine_start = $rperl_type . '_to_';
257 432         450 my $subroutine_start_length = length $subroutine_start;
258 432 50       701 if ((substr $subroutine, 0, $subroutine_start_length) eq $subroutine_start) {
259 0         0 $args_type_checking = 0;
260             }
261             }
262            
263             # do NOT enable argument type-checking for these subs
264 27 50       82 if (not $args_type_checking) {
265             # RPerl::diag('in Exporter::import(), @EXPORT_OK, NO CHECKING for non-RPerl or no-args or type-checking or type-conversion subroutine ' . $package_exporter . '::' . $subroutine . '()' . "\n");
266            
267             # define actual exported subroutine
268 7     7   42 no strict;
  7         13  
  7         2556  
269 0         0 *{ $package_importer . '::' . $subroutine } = \&{ $package_exporter . '::' . $subroutine }; # short form, symbol table direct, not strict, no type-checking
  0         0  
  0         0  
270 0         0 next;
271             }
272             # else { RPerl::diag('in Exporter::import(), YES CHECKING for RPerl subroutine ' . $subroutine . '()' . "\n"); }
273            
274             # form arguments check code name & call for repeated use
275 27         60 my $subroutine_arguments_check_code_name = $package_exporter . '::__CHECK_CODE_' . $subroutine;
276             # my $subroutine_arguments_check_code_call = 'eval "$' . $package_exporter . '::__CHECK_CODE_' . $subroutine . '";'; # DOES NOT WORK
277             # my $subroutine_arguments_check_code_call = 'eval qq{$' . $package_exporter . '::__CHECK_CODE_' . $subroutine . '};'; # DOES NOT WORK
278             # my $subroutine_arguments_check_code_call = '&{ ' . $subroutine_arguments_check_code_name . ' };'; # DOES NOT WORK
279             # my $subroutine_arguments_check_code_call = $subroutine_arguments_check_code_name . '();'; # DOES NOT WORK
280             # my $subroutine_arguments_check_code_call = 'eval ' . $subroutine_arguments_check_code_name . '();'; # DOES NOT WORK
281             # my $subroutine_arguments_check_code_call = 'eval ' . $subroutine_arguments_check_code_name . '() or die($EVAL_ERROR);'; # DOES NOT WORK, gives false die() on debug output
282             # my $subroutine_arguments_check_code_call = 'eval ' . $subroutine_arguments_check_code_name . '() or croak($EVAL_ERROR);'; # DOES NOT WORK, gives false die() on debug output, gives unnecessary eval() traces
283 27         67 my $subroutine_arguments_check_code_call = 'eval ' . $subroutine_arguments_check_code_name . '(); if ($EVAL_ERROR) { die($EVAL_ERROR); }'; # does work!
284             # my $subroutine_arguments_check_code_call = 'eval q{eval ' . $subroutine_arguments_check_code_name . '();};'; # DOES NOT WORK
285            
286             # DEBUG OUTPUT
287             # $subroutine_arguments_check_code_call .= 'print ' . $subroutine_arguments_check_code_name . '(), "\n\n";';
288             # $subroutine_arguments_check_code_call .= 'print eval ' . $subroutine_arguments_check_code_name . '(), "\n\n";';
289             # $subroutine_arguments_check_code_call .= q{::integer_CHECKTRACE( $_[0], '$hard_coded', 'hard_coded()' );};
290             # $subroutine_arguments_check_code_call .= q{::integer_CHECKTRACE( 21, '$hard_coded', 'hard_coded()' );};
291 27         55 $subroutine_arguments_check_code_call = 'print qq{BEFORE ARGS CHECK CODE EVAL1\n};' . $subroutine_arguments_check_code_call;
292 27         48 $subroutine_arguments_check_code_call .= 'print qq{AFTER ARGS CHECK CODE EVAL1\n};';
293            
294             # define actual exported subroutine
295 27         40 my $subroutine_definition_code = q{};
296 27 50       41 if (not defined &{$package_importer . '::' . $subroutine}) {
  27         179  
297 27         110 $subroutine_definition_code .=
298             '*' . $package_importer . '::' . $subroutine . ' = sub {' . "\n" .
299             # ' print q{in subroutine Exported by request!}, "\n";' . "\n" .
300             ' ' . $subroutine_arguments_check_code_call . "\n" .
301             ' return ' . $package_exporter . '::__UNCHECKED_' . $subroutine . '(@ARG);' . "\n" . ' };';
302             }
303            
304             # pass on each exported subroutine's associated __UNCHECKED & __CHECK_CODE & __CHECKED subroutine to the importing package
305             # $subroutine_definition_code .= "\n" . '*' . $package_importer . '::__CHECK_CODE_' . $subroutine . q{ = \\} . $subroutine_arguments_check_code_call; # DOES NOT WORK
306             # $subroutine_definition_code .= "\n" . '*' . $package_importer . '::__CHECK_CODE_' . $subroutine . ' = sub { return ' . $subroutine_arguments_check_code_name . '(); };'; # DOES NOT WORK
307 27 50       43 if (not defined &{$package_importer . '::__CHECK_CODE_' . $subroutine}) {
  27         123  
308 27         75 $subroutine_definition_code .= "\n" . 'sub ' . $package_importer . '::__CHECK_CODE_' . $subroutine . ' { return ' . $subroutine_arguments_check_code_name . '(); }';
309             }
310 27 50       67 if (not defined &{$package_importer . '::__UNCHECKED_' . $subroutine}) {
  27         126  
311 27         86 $subroutine_definition_code .= "\n" . 'sub ' . $package_importer . '::__UNCHECKED_' . $subroutine . ' { return ' . $package_exporter . '::__UNCHECKED_' . $subroutine . '(@ARG); }';
312             }
313 27 50       40 if (not defined &{$package_importer . '::__CHECKED_' . $subroutine}) {
  27         114  
314 27         72 $subroutine_definition_code .= "\n" . 'sub ' . $package_importer . '::__CHECKED_' . $subroutine . ' { return ' . $package_exporter . '::__CHECKED_' . $subroutine . '(@ARG); }';
315             }
316            
317             # RPerl::diag('in Exporter::import(), about to call eval() on requested $subroutine_definition_code = ' . "\n" . $subroutine_definition_code . "\n");
318             # eval($subroutine_definition_code) or (RPerl::diag('WARNING WSUXP01, Subroutine Exporter: Possible failure to export type-checking subroutine ' . $package_exporter . '::' . $subroutine . '(),' . "\n" . $EVAL_ERROR . "\n" . 'not croaking'));
319 27 50   7   4335 eval($subroutine_definition_code);
  7 50   0   4816  
  7 50   0   148  
  7 50   0   34  
  0 50   0   0  
  7 50   0   112  
  7     0   33  
  18     0   10180  
  18     0   459  
  18     0   79  
  0     0   0  
  18     0   376  
  18     0   77  
  15     0   8125  
  15     0   395  
  15     0   78  
  0     0   0  
  15     0   240  
  15     0   65  
  7     0   5151  
  7     0   183  
  7     0   33  
  0     0   0  
  7     0   457  
  7     0   41  
  7     0   6080  
  7     0   194  
  7     0   42  
  0     0   0  
  7     0   467  
  7     0   53  
  16     0   8626  
  16     0   389  
  16     0   83  
  0     0   0  
  16     0   526  
  16     0   73  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0            
  0            
  0            
320             # if ($EVAL_ERROR) { croak q{ERROR ESUXP03, Subroutine Exporter: Failed to export type-checking subroutine '} . $package_exporter . '::' . $subroutine . q{()',} . "\n" . $EVAL_ERROR . "\n" . 'croaking'; } # does work, gives unnecessary eval() traces
321 27 50       132 if ($EVAL_ERROR) { die q{ERROR ESUXP03, Subroutine Exporter: Failed to export type-checking subroutine '} . $package_exporter . '::' . $subroutine . q{()',} . "\n" . $EVAL_ERROR . "\n" . 'dying' . "\n"; }
  0         0  
322             }
323             # requested subroutine is not in @EXPORT or @EXPORT_OK, error
324             else {
325 0         0 croak q{ERROR ESUXP02, Subroutine Exporter: Failed to export requested subroutine '} . $subroutine . q{()' from package '} . $package_exporter . q{' into requesting package '} . $package_importer . q{', subroutine not found in exporting package's @EXPORT or @EXPORT_OK, croaking};
326             }
327             }
328             }
329             }
330             }
331              
332             # USAGE OPTIONS C & D: force export of all subroutines in @EXPORT
333 505 100       837 if (not scalar @{$package_exporter . '::EXPORT'}) { return; }
  505         2292  
  11         1364  
334 494         795 foreach my $subroutine_or_variable (@{$package_exporter . '::EXPORT'}) {
  494         1558  
335 14198         22083 my $possible_sigil = substr $subroutine_or_variable, 0, 1;
336             # RPerl::diag(q{in Exporter::import(), have forced $subroutine_or_variable = '}, $subroutine_or_variable, q{'}, "\n"); # DEV NOTE: causes false errors in t/12_parse.t???
337             # RPerl::diag(q{in Exporter::import(), have $possible_sigil = '}, $possible_sigil, q{'}, "\n"); # DEV NOTE: causes false errors in t/12_parse.t???
338 14198 50 33     57443 if (($possible_sigil eq '$') or
      33        
      33        
339             ($possible_sigil eq '@') or
340             ($possible_sigil eq '%') or
341             ($possible_sigil eq '*')) {
342 0         0 my $variable = $subroutine_or_variable;
343 0         0 my $variable_no_sigil = substr $variable, 1;
344              
345             # NEED ANSWER: can not check for variable existence here, may not be initialized yet???
346 0 0       0 if (not defined *{ $package_exporter . '::' . $variable_no_sigil }) {
  0         0  
347 0         0 croak q{ERROR EVAXP02, Variable Exporter: Failed to export forced variable '} . $variable . q{' from package '} . $package_exporter . q{' into requesting package '} . $package_importer . q{', variable does not exist, croaking};
348             }
349              
350             # RPerl::diag(q{in Exporter::import(), have $package_exporter = '}, $package_exporter, q{'}, "\n"); # DEV NOTE: causes false errors in t/12_parse.t???
351             # RPerl::diag(q{in Exporter::import(), have forced $variable = '}, $variable, q{'}, "\n"); # DEV NOTE: causes false errors in t/12_parse.t???
352             # RPerl::diag(q{in Exporter::import(), have $possible_sigil = '}, $possible_sigil, q{'}, "\n"); # DEV NOTE: causes false errors in t/12_parse.t???
353              
354 7     7   47 no strict;
  7         14  
  7         2016  
355             # define actual exported variable
356             # DEV NOTE: can not test for pre-existing variables because there is no valid defined(@array), etc.
357 0 0       0 if ($possible_sigil eq '$') { # SCALAR
    0          
    0          
    0          
358 0         0 *{ $package_importer . '::' . $variable_no_sigil } = \${ $package_exporter . '::' . $variable_no_sigil };
  0         0  
  0         0  
359             }
360             elsif ($possible_sigil eq '@') { # ARRAY
361 0         0 *{ $package_importer . '::' . $variable_no_sigil } = \@{ $package_exporter . '::' . $variable_no_sigil };
  0         0  
  0         0  
362             }
363             elsif ($possible_sigil eq '%') { # HASH
364 0         0 *{ $package_importer . '::' . $variable_no_sigil } = \%{ $package_exporter . '::' . $variable_no_sigil };
  0         0  
  0         0  
365             }
366             elsif ($possible_sigil eq '*') { # TYPEGLOB
367 0         0 *{ $package_importer . '::' . $variable_no_sigil } = *{ $package_exporter . '::' . $variable_no_sigil };
  0         0  
  0         0  
368             }
369             }
370             else {
371 14198         17174 my $subroutine = $subroutine_or_variable;
372              
373 14198 50       38165 if ($possible_sigil eq '&') {
    50          
374             # drop unnecessary ampersand sigils
375 0         0 substr $subroutine, 0, 1, q{};
376             }
377             elsif ($possible_sigil !~ /\w/) {
378 0         0 croak q{ERROR ESYXP03, Subroutine & Variable Exporter: Failed to export symbol '} . $subroutine_or_variable . q{' from package '} . $package_exporter . q{' into requesting package '} . $package_importer . q{', symbol begins with unrecognized character '}, $possible_sigil, q{', croaking};
379             }
380              
381             # enable args type-checking except for exempted subs below
382 14198         16454 my $args_type_checking = 1;
383            
384             # type-checking subs
385 14198 100 100     45278 if (($subroutine =~ m/_CHECK$/) or
    50 33        
      33        
      0        
386             ($subroutine =~ m/_CHECKTRACE$/)) {
387             # RPerl::diag('in Exporter::import(), @EXPORT, NO CHECKING for type-checking subroutine ' . $package_exporter . '::' . $subroutine . '()' . "\n");
388 4338         5317 $args_type_checking = 0;
389             }
390             # non-RPerl subs
391             # DEV NOTE, CORRELATION #rp051: hard-coded list of non-RPerl subroutines
392             # DEV NOTE, CORRELATION #rp052: gsl_matrix_to_*() and gsl_matrix_rows() and gsl_matrix_cols() are RPerl subroutines
393             elsif (($subroutine =~ m/^gsl_/) and
394             ($subroutine !~ m/^gsl_matrix_to/) and
395             ($subroutine ne 'gsl_matrix_rows') and
396             ($subroutine ne 'gsl_matrix_cols')) {
397             # RPerl::diag('in Exporter::import(), @EXPORT, NO CHECKING for non-RPerl subroutine ' . $package_exporter . '::' . $subroutine . '()' . "\n");
398 0         0 $args_type_checking = 0;
399             }
400            
401             =DISABLED_NO_ARGS
402             # DEV NOTE, CORRELATION #rp053: even with the upgrade to normal Perl subroutine headers, we must still activate subroutines w/out args or when type-checking is explicitly disabled with CHECK OFF, in order for RPerl::Exporter to work properly, presumably because Exporter.pm runs before Class.pm and thus we can not test for the existence of __CHECKED_*() subroutines in RPerl::Exporter::import()
403             # subs with no args (and thus no arg type-checking)
404             # none of the below tests work, presumably because Exporter.pm is called before Class.pm
405             # elsif (not defined *{ $package_exporter . '::__CHECK_CODE_' . $subroutine }) {
406             # elsif (not defined &{ $package_exporter . '::__CHECK_CODE_' . $subroutine }) {
407             # elsif (not defined &{ $package_exporter . '::__CHECKED_' . $subroutine }) {
408             # elsif (not exists *{ $package_exporter . '::__CHECKED_' . $subroutine }) {
409             # elsif (not exists &{ $package_exporter . '::__CHECKED_' . $subroutine }) {
410             elsif (0) {
411             # RPerl::diag('in Exporter::import(), @EXPORT, NO CHECKING for no-args subroutine ' . $package_exporter . '::' . $subroutine . '()' . "\n");
412             $args_type_checking = 0;
413             }
414            
415             if ($package_exporter eq 'RPerl::Test::TypeCheckingOn::AllTypes') {
416             &{ $package_exporter . '::__CHECKED_' . $subroutine }(0);
417             die 'TMP DEBUG';
418             }
419             =cut
420            
421             # RPerl::diag('in Exporter::import(), have $SUPPORTED_ALL etc = ' . Dumper([@{$SUPPORTED_ALL}, @{$SUPPORTED_SPECIAL}]). "\n");
422            
423             # type-conversion subs
424 14198         15783 foreach my $rperl_type (sort @{[@{$SUPPORTED_ALL}, @{$SUPPORTED_SPECIAL}]}) {
  14198         14561  
  14198         17736  
  14198         66708  
425 227168         264810 my $subroutine_start = $rperl_type . '_to_';
426 227168         230991 my $subroutine_start_length = length $subroutine_start;
427 227168 100       352115 if ((substr $subroutine, 0, $subroutine_start_length) eq $subroutine_start) {
428             # RPerl::diag('in Exporter::import(), @EXPORT, NO CHECKING for type-conversion subroutine ' . $package_exporter . '::' . $subroutine . '()' . "\n");
429 9747         12264 $args_type_checking = 0;
430             }
431             }
432            
433             # do NOT enable argument type-checking for these subs
434 14198 100       29167 if (not $args_type_checking) {
435             # RPerl::diag('in Exporter::import(), @EXPORT, NO CHECKING for non-RPerl or no-args or type-checking or type-conversion subroutine ' . $package_exporter . '::' . $subroutine . '()' . "\n");
436            
437             # define actual exported subroutine
438 7     7   47 no strict;
  7         13  
  7         2259  
439 14085         14915 *{ $package_importer . '::' . $subroutine } = \&{ $package_exporter . '::' . $subroutine }; # short form, symbol table direct, not strict, no type-checking
  14085         51445  
  14085         36731  
440 14085         44111 next;
441             }
442             # else { RPerl::diag('in Exporter::import(), YES CHECKING for RPerl subroutine ' . $subroutine . '()' . "\n"); }
443            
444             # form arguments check code name & call for repeated use
445 113         254 my $subroutine_arguments_check_code_name = $package_exporter . '::__CHECK_CODE_' . $subroutine;
446            
447             # my $subroutine_arguments_check_code_call = 'eval "$' . $package_exporter . '::__CHECK_CODE_' . $subroutine . '";'; # DOES NOT WORK
448             # my $subroutine_arguments_check_code_call = 'eval qq{$' . $package_exporter . '::__CHECK_CODE_' . $subroutine . '};'; # DOES NOT WORK
449             # my $subroutine_arguments_check_code_call = '&{ ' . $package_exporter . '::__CHECK_CODE_' . $subroutine . ' };'; # DOES NOT WORK
450             # my $subroutine_arguments_check_code_call = $subroutine_arguments_check_code_name . '();';
451             # my $subroutine_arguments_check_code_call = 'eval ' . $subroutine_arguments_check_code_name . '();';
452             # $subroutine_arguments_check_code_call .= 'print qq{AFTER ARGS CHECK CODE EVAL2\n};';
453 113         213 my $subroutine_arguments_check_code_call = 'eval ' . $subroutine_arguments_check_code_name . '(); if ($EVAL_ERROR) { die($EVAL_ERROR); }'; # does work!
454            
455             # define actual exported subroutine
456 113         173 my $subroutine_definition_code = q{};
457 113 100       135 if (not defined &{$package_importer . '::' . $subroutine}) {
  113         598  
458 89         262 $subroutine_definition_code .=
459             '*' . $package_importer . '::' . $subroutine . ' = sub {' . "\n" .
460             # ' print q{in subroutine ' . $package_exporter . '::__CHECKED_' . $subroutine . '() Exported by force!}, "\n";' . "\n" . # DEBUG USE ONLY!
461             ' ' . $subroutine_arguments_check_code_call . "\n" .
462             ' return ' . $package_exporter . '::__CHECKED_' . $subroutine . '(@ARG);' . "\n" . ' };';
463             }
464            
465             # pass on each exported subroutine's associated __UNCHECKED & __CHECK_CODE & __CHECKED subroutine to the importing package
466             # $subroutine_definition_code .= "\n" . '*' . $package_importer . '::__CHECK_CODE_' . $subroutine . q{ = \\} . $subroutine_arguments_check_code_call;
467             # $subroutine_definition_code .= "\n" . '*' . $package_importer . '::__CHECK_CODE_' . $subroutine . ' = sub { return ' . $subroutine_arguments_check_code_name . '(); };';
468 113 100       178 if (not defined &{$package_importer . '::__CHECK_CODE_' . $subroutine}) {
  113         451  
469 89         196 $subroutine_definition_code .= "\n" . 'sub ' . $package_importer . '::__CHECK_CODE_' . $subroutine . ' { return ' . $subroutine_arguments_check_code_name . '(); }';
470             }
471 113 100       159 if (not defined &{$package_importer . '::__UNCHECKED_' . $subroutine}) {
  113         410  
472 89         223 $subroutine_definition_code .= "\n" . 'sub ' . $package_importer . '::__UNCHECKED_' . $subroutine . ' { return ' . $package_exporter . '::__UNCHECKED_' . $subroutine . '(@ARG); }';
473             }
474 113 100       142 if (not defined &{$package_importer . '::__CHECKED_' . $subroutine}) {
  113         395  
475 89         224 $subroutine_definition_code .= "\n" . 'sub ' . $package_importer . '::__CHECKED_' . $subroutine . ' { return ' . $package_exporter . '::__CHECKED_' . $subroutine . '(@ARG); }';
476             }
477            
478             # RPerl::diag('in Exporter::import(), about to call eval() on forced $subroutine_definition_code = ' . "\n" . $subroutine_definition_code . "\n");
479             # eval($subroutine_definition_code) or (RPerl::diag('WARNING WSUXP02, Subroutine Exporter: Possible failure to export type-checking subroutine ' . $package_exporter . '::' . $subroutine . '(),' . "\n" . $EVAL_ERROR . "\n" . 'not croaking'));
480 113 0   0   12196 eval($subroutine_definition_code);
  0 0   0   0  
  0 0   0   0  
  0 0   0   0  
  0 0   0   0  
  0 0   0   0  
  0 50   0   0  
  0 50   0   0  
  0 0   0   0  
  0 0   0   0  
  0 0   0   0  
  0 0   0   0  
  0 0   0   0  
  0 0   0   0  
  0 0   0   0  
  0 0   0   0  
  0 0   0   0  
  0 0   2   0  
  0 0   0   0  
  0 0   0   0  
  0 0   0   0  
  0 0   0   0  
  0 0   0   0  
  0 0   0   0  
  0 0   0   0  
  22 0   0   2661  
  22 0   0   105  
  0 0   0   0  
  22 0   0   327  
  2 0   0   37  
  2 0   0   12  
  0 0   0   0  
  2 0   0   35  
  0 0   0   0  
  0 0   0   0  
  0 0   0   0  
  0 0   0   0  
  0 0   0   0  
  0 0   0   0  
  0 0   0   0  
  0 0   0   0  
  0 0   0   0  
  0 0   0   0  
  0 0   0   0  
  0 0   0   0  
  0 0   0   0  
  0 0   0   0  
  0 0   0   0  
  0 0   0   0  
  0 0   0   0  
  0 0   0   0  
  0 0   0   0  
  0 0   0   0  
  0 0   0   0  
  0 0   22   0  
  0 0   0   0  
  0 0   0   0  
  0 0   0   0  
  0 0   0   0  
  0 0   0   0  
  0 0   0   0  
  0 0   0   0  
  0 0   0   0  
  0 0   0   0  
  0 0   0   0  
  0 0   0   0  
  0 0   0   0  
  0 0   0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     2   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     22   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  2         36  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  22         357  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  2         42  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  22         366  
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
481             # if ($EVAL_ERROR) { croak q{ERROR ESUXP04, Subroutine Exporter: Failed to export type-checking subroutine '} . $package_exporter . '::' . $subroutine . q{()',} . "\n" . $EVAL_ERROR . "\n" . 'croaking'; } # does work, gives unnecessary eval() traces
482 113 50       3369 if ($EVAL_ERROR) { die q{ERROR ESUXP04, Subroutine Exporter: Failed to export type-checking subroutine '} . $package_exporter . '::' . $subroutine . q{()',} . "\n" . $EVAL_ERROR . "\n" . 'dying' . "\n"; }
  0         0  
483             }
484            
485             =DISABLED_LONG_FORM_EVAL_ANON_SUB_STRICT
486             # my @subroutines = (eval '@' . $package_exporter . '::EXPORT')
487             # or (die q{ERROR ESUXPxx: Failed to read @EXPORT variable for package '} . $package_exporter . q{', did you forget to define @} . $package_exporter . q{::EXPORT in your code?} . "\n" . $EVAL_ERROR . "\n" . 'dying');
488             # print 'in import(), have @subroutines = ' . Dumper(\@subroutines) . "\n";
489            
490             # foreach my $subroutine (@subroutines) {
491             # my $eval_string = '*' . $package_importer . '::' . $subroutine . ' = sub { return ' . $package_exporter . '::' . $subroutine . '(@_); };';
492             # print 'have $eval_string = ' . "\n" . $eval_string . "\n";
493             # eval $eval_string
494             # or (die q{ERROR ESUXPxx: Failed to export subroutine '} . $subroutine . q{()' from package '} . $package_exporter . q{' to package '} . $package_importer . q{'} . "\n" . $EVAL_ERROR . "\n" . 'dying');
495             # }
496             =cut
497             }
498             }
499              
500             1;