File Coverage

blib/lib/Importer.pm
Criterion Covered Total %
statement 336 350 96.0
branch 154 176 87.5
condition 121 175 69.1
subroutine 40 40 100.0
pod 17 19 89.4
total 668 760 87.8


line stmt bran cond sub pod time code
1             package Importer;
2 7     7   43781 use strict qw/vars subs/; # Not refs!
  7         90  
  7         496  
3 7     7   62 use warnings; no warnings 'once';
  7     7   41  
  7         149  
  7         65  
  7         50  
  7         13575  
4              
5             our $VERSION = '0.024';
6              
7             my %SIG_TO_SLOT = (
8             '&' => 'CODE',
9             '$' => 'SCALAR',
10             '%' => 'HASH',
11             '@' => 'ARRAY',
12             '*' => 'GLOB',
13             );
14              
15             our %IMPORTED;
16              
17             # This will be used to check if an import arg is a version number
18             my %NUMERIC = map +($_ => 1), 0 .. 9;
19              
20             sub IMPORTER_MENU() {
21             return (
22             export_ok => [qw/optimal_import/],
23             export_anon => {
24             import => sub {
25 0     1   0 my $from = shift;
26 0         0 my @caller = caller(0);
27              
28 0 50 0     0 _version_check($from, \@caller, shift @_) if @_ && $NUMERIC{substr($_[0], 0, 1)};
29              
30 0         0 my $file = _mod_to_file($from);
31 0 50       0 _load_file(\@caller, $file) unless $INC{$file};
32              
33 0 50       0 return if optimal_import($from, $caller[0], \@caller, @_);
34              
35 0         0 my $self = __PACKAGE__->new(
36             from => $from,
37             caller => \@caller,
38             );
39              
40 0         0 $self->do_import($caller[0], @_);
41             },
42             },
43 1     2 0 7 );
44             }
45              
46             ###########################################################################
47             #
48             # These are class methods
49             # import and unimport are what you would expect.
50             # import_into and unimport_from are the indirect forms you can use in other
51             # package import() methods.
52             #
53             # These all attempt to do a fast optimal-import if possible, then fallback to
54             # the full-featured import that constructs an object when needed.
55             #
56              
57             sub import {
58 15     16   6605 my $class = shift;
59              
60 15         96 my @caller = caller(0);
61              
62 15 100 66     121 _version_check($class, \@caller, shift @_) if @_ && $NUMERIC{substr($_[0], 0, 1)};
63              
64 14 100       105 return unless @_;
65              
66 13         21 my ($from, @args) = @_;
67              
68 13         29 my $file = _mod_to_file($from);
69 13 100       42 _load_file(\@caller, $file) unless $INC{$file};
70              
71 13 100       54237 return if optimal_import($from, $caller[0], \@caller, @args);
72              
73 11         44 my $self = $class->new(
74             from => $from,
75             caller => \@caller,
76             );
77              
78 11         32 $self->do_import($caller[0], @args);
79             }
80              
81             sub unimport {
82 5     6   2073 my $class = shift;
83 5         30 my @caller = caller(0);
84              
85 5         18 my $self = $class->new(
86             from => $caller[0],
87             caller => \@caller,
88             );
89              
90 5         14 $self->do_unimport(@_);
91             }
92              
93             sub import_into {
94 2     3 1 1995 my $class = shift;
95 2         5 my ($from, $into, @args) = @_;
96              
97 2         2 my @caller;
98              
99 2 50       13 if (ref($into)) {
    100          
100 0         0 @caller = @$into;
101 0         0 $into = $caller[0];
102             }
103             elsif ($into =~ m/^\d+$/) {
104 1         6 @caller = caller($into + 1);
105 1         2 $into = $caller[0];
106             }
107             else {
108 1         8 @caller = caller(0);
109             }
110              
111 2         6 my $file = _mod_to_file($from);
112 2 50       6 _load_file(\@caller, $file) unless $INC{$file};
113              
114 2 50       4 return if optimal_import($from, $into, \@caller, @args);
115              
116 0         0 my $self = $class->new(
117             from => $from,
118             caller => \@caller,
119             );
120              
121 0         0 $self->do_import($into, @args);
122             }
123              
124             sub unimport_from {
125 4     4 1 2159 my $class = shift;
126 4         8 my ($from, @args) = @_;
127              
128 4         4 my @caller;
129 4 100       18 if ($from =~ m/^\d+$/) {
130 2         14 @caller = caller($from + 1);
131 2         4 $from = $caller[0];
132             }
133             else {
134 2         13 @caller = caller(0);
135             }
136              
137 4         9 my $self = $class->new(
138             from => $from,
139             caller => \@caller,
140             );
141              
142 4         8 $self->do_unimport(@args);
143             }
144              
145             ###########################################################################
146             #
147             # Constructors
148             #
149              
150             sub new {
151 50     50 1 19496 my $class = shift;
152 50         117 my %params = @_;
153              
154 50   100     175 my $caller = $params{caller} || [caller()];
155              
156             die "You must specify a package to import from at $caller->[1] line $caller->[2].\n"
157 50 100       90 unless $params{from};
158              
159             return bless {
160             from => $params{from},
161             caller => $params{caller}, # Do not use our caller.
162 49         169 }, $class;
163             }
164              
165             ###########################################################################
166             #
167             # Shortcuts for getting symbols without any namespace modifications
168             #
169              
170             sub get {
171 2     2 1 1135 my $proto = shift;
172 2         10 my @caller = caller(1);
173              
174 2 100       10 my $self = ref($proto) ? $proto : $proto->new(
175             from => shift(@_),
176             caller => \@caller,
177             );
178              
179 2         2 my %result;
180 2     4   11 $self->do_import($caller[0], @_, sub { $result{$_[0]} = $_[1] });
  4         7  
181 2         20 return \%result;
182             }
183              
184             sub get_list {
185 2     2 1 1455 my $proto = shift;
186 2         12 my @caller = caller(1);
187              
188 2 100       8 my $self = ref($proto) ? $proto : $proto->new(
189             from => shift(@_),
190             caller => \@caller,
191             );
192              
193 2         3 my @result;
194 2     4   8 $self->do_import($caller[0], @_, sub { push @result => $_[1] });
  4         5  
195 2         17 return @result;
196             }
197              
198             sub get_one {
199 3     3 1 1417 my $proto = shift;
200 3         18 my @caller = caller(1);
201              
202 3 100       11 my $self = ref($proto) ? $proto : $proto->new(
203             from => shift(@_),
204             caller => \@caller,
205             );
206              
207 3         3 my $result;
208 3     4   12 $self->do_import($caller[0], @_, sub { $result = $_[1] });
  4         4  
209 3         23 return $result;
210             }
211              
212             ###########################################################################
213             #
214             # Object methods
215             #
216              
217             sub do_import {
218 18     18 1 19 my $self = shift;
219              
220 18         38 my ($into, $versions, $exclude, $import, $set) = $self->parse_args(@_);
221              
222             # Exporter supported multiple version numbers being listed...
223 18 100       39 _version_check($self->from, $self->get_caller, @$versions) if @$versions;
224              
225 18 50       61 return unless @$import;
226              
227 18 100       688 $self->_handle_fail($into, $import) if $self->menu($into)->{fail};
228 18         41 $self->_set_symbols($into, $exclude, $import, $set);
229             }
230              
231             sub do_unimport {
232 11     11 1 2231 my $self = shift;
233              
234 11         18 my $from = $self->from;
235 11 100       43 my $imported = $IMPORTED{$from} or $self->croak("'$from' does not have any imports to remove");
236              
237 9         16 my %allowed = map { $_ => 1 } @$imported;
  25         42  
238              
239 9 100       27 my @args = @_ ? @_ : @$imported;
240              
241 9         8 my $stash = \%{"$from\::"};
  9         21  
242              
243 9         15 for my $name (@args) {
244 18         19 $name =~ s/^&//;
245              
246 18 100       40 $self->croak("Sub '$name' was not imported using " . ref($self)) unless $allowed{$name};
247              
248 16         32 my $glob = delete $stash->{$name};
249 16         32 local *GLOBCLONE = *$glob;
250              
251 16         20 for my $type (qw/SCALAR HASH ARRAY FORMAT IO/) {
252 80 100       53 next unless defined(*{$glob}{$type});
  80         1468  
253 18         18 *{"$from\::$name"} = *{$glob}{$type}
  18         54  
  18         21  
254             }
255             }
256             }
257              
258 161     161 1 594 sub from { $_[0]->{from} }
259              
260             sub from_file {
261 5     5 1 758 my $self = shift;
262              
263 5   66     26 $self->{from_file} ||= _mod_to_file($self->{from});
264              
265 5         9 return $self->{from_file};
266             }
267              
268             sub load_from {
269 3     3 1 32 my $self = shift;
270 3         7 my $from_file = $self->from_file;
271 3         4 my $this_file = __FILE__;
272              
273 3 100       7 return if $INC{$from_file};
274              
275 2         4 my $caller = $self->get_caller;
276              
277 2         6 _load_file($caller, $from_file);
278             }
279              
280             sub get_caller {
281 57     57 1 60 my $self = shift;
282 57 100       146 return $self->{caller} if $self->{caller};
283              
284 14         10 my $level = 1;
285 14         82 while(my @caller = caller($level++)) {
286 27 100 66     157 return \@caller if @caller && !$caller[0]->isa(__PACKAGE__);
287 13 50       73 last unless @caller;
288             }
289              
290             # Fallback
291 0         0 return [caller(0)];
292             }
293              
294             sub croak {
295 15     15 1 24 my $self = shift;
296 15         13 my ($msg) = @_;
297 15         21 my $caller = $self->get_caller;
298 15   50     28 my $file = $caller->[1] || 'unknown file';
299 15   50     26 my $line = $caller->[2] || 'unknown line';
300 15         94 die "$msg at $file line $line.\n";
301             }
302              
303             sub carp {
304 2     2 1 382 my $self = shift;
305 2         4 my ($msg) = @_;
306 2         4 my $caller = $self->get_caller;
307 2   50     7 my $file = $caller->[1] || 'unknown file';
308 2   50     5 my $line = $caller->[2] || 'unknown line';
309 2         32 warn "$msg at $file line $line.\n";
310             }
311              
312             sub menu {
313 136     136 1 896 my $self = shift;
314 136         99 my ($into) = @_;
315              
316 136 100       192 $self->croak("menu() requires the name of the destination package")
317             unless $into;
318              
319 135         153 my $for = $self->{menu_for};
320 135 100 100     388 delete $self->{menu} if $for && $for ne $into;
321 135   66     1084 return $self->{menu} || $self->reload_menu($into);
322             }
323              
324             sub reload_menu {
325 34     34 1 48 my $self = shift;
326 34         35 my ($into) = @_;
327              
328 34 100       51 $self->croak("reload_menu() requires the name of the destination package")
329             unless $into;
330              
331 33         46 my $from = $self->from;
332              
333 33 100       27 if (my $menu_sub = *{"$from\::IMPORTER_MENU"}{CODE}) {
  33         130  
334             # Hook, other exporter modules can define this method to be compatible with
335             # Importer.pm
336              
337 9         15 my %got = $from->$menu_sub($into, $self->get_caller);
338              
339 9   100     667 $got{export} ||= [];
340 9   100     22 $got{export_ok} ||= [];
341 9   100     23 $got{export_tags} ||= {};
342 9   100     20 $got{export_fail} ||= [];
343 9   100     20 $got{export_anon} ||= {};
344 9   50     29 $got{export_magic} ||= {};
345              
346             $self->croak("'$from' provides both 'generate' and 'export_gen' in its IMPORTER_MENU (They are exclusive, module must pick 1)")
347 9 100 66     27 if $got{export_gen} && $got{generate};
348              
349 8   100     49 $got{export_gen} ||= {};
350              
351 8         15 $self->{menu} = $self->_build_menu($into => \%got, 1);
352             }
353             else {
354 24         22 my %got;
355 24         18 $got{export} = \@{"$from\::EXPORT"};
  24         63  
356 24         16 $got{export_ok} = \@{"$from\::EXPORT_OK"};
  24         50  
357 24         22 $got{export_tags} = \%{"$from\::EXPORT_TAGS"};
  24         58  
358 24         22 $got{export_fail} = \@{"$from\::EXPORT_FAIL"};
  24         52  
359 24         19 $got{export_gen} = \%{"$from\::EXPORT_GEN"};
  24         41  
360 24         21 $got{export_anon} = \%{"$from\::EXPORT_ANON"};
  24         41  
361 24         23 $got{export_magic} = \%{"$from\::EXPORT_MAGIC"};
  24         47  
362              
363 24         41 $self->{menu} = $self->_build_menu($into => \%got, 0);
364             }
365              
366 31         77 $self->{menu_for} = $into;
367              
368 31         105 return $self->{menu};
369             }
370              
371             sub _build_menu {
372 32     32   30 my $self = shift;
373 32         35 my ($into, $got, $new_style) = @_;
374              
375 32         42 my $from = $self->from;
376              
377 32   50     67 my $export = $got->{export} || [];
378 32   50     52 my $export_ok = $got->{export_ok} || [];
379 32   50     60 my $export_tags = $got->{export_tags} || {};
380 32   50     55 my $export_fail = $got->{export_fail} || [];
381 32   50     51 my $export_anon = $got->{export_anon} || {};
382 32   50     78 my $export_gen = $got->{export_gen} || {};
383 32   50     47 my $export_magic = $got->{export_magic} || {};
384              
385 32         31 my $generate = $got->{generate};
386              
387             $generate ||= sub {
388 7     7   6249 my $symbol = shift;
389 7         32 my ($sig, $name) = ($symbol =~ m/^(\W?)(.*)$/);
390 7   100     22 $sig ||= '&';
391              
392 7         13 my $do = $export_gen->{"${sig}${name}"};
393 7 50 100     40 $do ||= $export_gen->{$name} if !$sig || $sig eq '&';
      33        
394              
395 7 100       12 return undef unless $do;
396              
397 6         13 $from->$do($into, $symbol);
398 32 100 50     178 } if $export_gen && keys %$export_gen;
      66        
399              
400 32         34 my $lookup = {};
401 32         29 my $exports = {};
402 32         67 for my $sym (@$export, @$export_ok, keys %$export_gen, keys %$export_anon) {
403 273         644 my ($sig, $name) = ($sym =~ m/^(\W?)(.*)$/);
404 273   100     548 $sig ||= '&';
405              
406 273         352 $lookup->{"${sig}${name}"} = 1;
407 273 100       446 $lookup->{$name} = 1 if $sig eq '&';
408              
409 273 100       372 next if $export_gen->{"${sig}${name}"};
410 266 100 66     487 next if $sig eq '&' && $export_gen->{$name};
411 259 50 33     387 next if $got->{generate} && $generate->("${sig}${name}");
412              
413 259         239 my $fqn = "$from\::$name";
414             # We cannot use *{$fqn}{TYPE} here, it breaks for autoloaded subs, this
415             # does not:
416             $exports->{"${sig}${name}"} = $export_anon->{$sym} || (
417             $sig eq '&' ? \&{$fqn} :
418             $sig eq '$' ? \${$fqn} :
419             $sig eq '@' ? \@{$fqn} :
420             $sig eq '%' ? \%{$fqn} :
421 259   66     494 $sig eq '*' ? \*{$fqn} :
422             # Sometimes people (CGI::Carp) put invalid names (^name=) into
423             # @EXPORT. We simply go to 'next' in these cases. These modules
424             # have hooks to prevent anyone actually trying to import these.
425             next
426             );
427             }
428              
429 32   100     214 my $f_import = $new_style || $from->can('import');
430             $self->croak("'$from' does not provide any exports")
431             unless $new_style
432             || keys %$exports
433             || $from->isa('Exporter')
434 32 100 100     154 || ($INC{'Exporter.pm'} && $f_import && $f_import == \&Exporter::import);
      100        
      66        
      66        
      66        
435              
436             # Do not cleanup or normalize the list added to the DEFAULT tag, legacy....
437 31         120 my $tags = {
438             %$export_tags,
439             'DEFAULT' => [ @$export ],
440             };
441              
442             # Add 'ALL' tag unless already specified. We want to normalize it.
443 31   100     146 $tags->{ALL} ||= [ sort grep {m/^[\&\$\@\%\*]/} keys %$lookup ];
  509         660  
444              
445             my $fail = @$export_fail ? {
446             map {
447 31 100       75 my ($sig, $name) = (m/^(\W?)(.*)$/);
  24         64  
448 24   100     57 $sig ||= '&';
449 24 100       89 ("${sig}${name}" => 1, $sig eq '&' ? ($name => 1) : ())
450             } @$export_fail
451             } : undef;
452              
453 31         102 my $menu = {
454             lookup => $lookup,
455             exports => $exports,
456             tags => $tags,
457             fail => $fail,
458             generate => $generate,
459             magic => $export_magic,
460             };
461              
462 31         75 return $menu;
463             }
464              
465             sub parse_args {
466 31     31 0 831 my $self = shift;
467 31         43 my ($into, @args) = @_;
468              
469 31         57 my $menu = $self->menu($into);
470              
471 31         64 my @out = $self->_parse_args($into, $menu, \@args);
472 28         33 pop @out;
473 28         130 return @out;
474             }
475              
476             sub _parse_args {
477 47     47   43 my $self = shift;
478 47         52 my ($into, $menu, $args, $is_tag) = @_;
479              
480 47         62 my $from = $self->from;
481 47         63 my $main_menu = $self->menu($into);
482 47   33     69 $menu ||= $main_menu;
483              
484             # First we strip out versions numbers and setters, this simplifies the logic late.
485 47         39 my @sets;
486             my @versions;
487 0         0 my @leftover;
488 47         55 for my $arg (@$args) {
489 7     7   95 no warnings 'void';
  7         64  
  6         8306  
490              
491             # Code refs are custom setters
492             # If the first character is an ASCII numeric then it is a version number
493 188 100 50     248 push @sets => $arg and next if ref($arg) eq 'CODE';
494 178 100 0     251 push @versions => $arg xor next if $NUMERIC{substr($arg, 0, 1)};
495 175         170 push @leftover => $arg;
496             }
497              
498 47 50       75 $self->carp("Multiple setters specified, only 1 will be used") if @sets > 1;
499 47         44 my $set = pop @sets;
500              
501 47         40 $args = \@leftover;
502 47 100 100     153 @$args = (':DEFAULT') unless $is_tag || @$args || @versions;
      66        
503              
504 47         41 my %exclude;
505             my @import;
506              
507 47         80 while(my $full_arg = shift @$args) {
508 174         110 my $arg = $full_arg;
509 174         145 my $lead = substr($arg, 0, 1);
510              
511 174         113 my ($spec, $exc);
512 174 100       174 if ($lead eq '!') {
513 5         6 $exc = $lead;
514              
515 5 100       7 if ($arg eq '!') {
516             # If the current arg is just '!' then we are negating the next item.
517 1         2 $arg = shift @$args;
518             }
519             else {
520             # Strip off the '!'
521 4         6 substr($arg, 0, 1, '');
522             }
523              
524             # Exporter.pm legacy behavior
525             # negated first item implies starting with default set:
526 5 50 66     17 unshift @$args => ':DEFAULT' unless @import || keys %exclude || @versions;
      66        
527              
528             # Now we have a new lead character
529 5         5 $lead = substr($arg, 0, 1);
530             }
531             else {
532             # If the item is followed by a reference then they are asking us to
533             # do something special...
534 169 100       235 $spec = ref($args->[0]) eq 'HASH' ? shift @$args : {};
535             }
536              
537 174 100       228 if($lead eq ':') {
538 17         23 substr($arg, 0, 1, '');
539 17 100       39 my $tag = $menu->{tags}->{$arg} or $self->croak("$from does not export the :$arg tag");
540              
541 16         64 my (undef, $cvers, $cexc, $cimp, $cset, $newmenu) = $self->_parse_args($into, $menu, $tag, $arg);
542              
543 16 50       47 $self->croak("Exporter specified version numbers (" . join(', ', @$cvers) . ") in the :$arg tag!")
544             if @$cvers;
545              
546 16 50       22 $self->croak("Exporter specified a custom symbol setter in the :$arg tag!")
547             if $cset;
548              
549             # Merge excludes
550 16         38 %exclude = (%exclude, %$cexc);
551              
552 16 100 66     70 if ($exc) {
    100          
553 1 50       2 $exclude{$_} = 1 for grep {!ref($_) && substr($_, 0, 1) ne '+'} map {$_->[0]} @$cimp;
  2         12  
  2         3  
554             }
555             elsif ($spec && keys %$spec) {
556             $self->croak("Cannot use '-as' to rename multiple symbols included by: $full_arg")
557 3 100 66     17 if $spec->{'-as'} && @$cimp > 1;
558              
559 2         3 for my $set (@$cimp) {
560 5         7 my ($sym, $cspec) = @$set;
561              
562             # Start with a blind squash, spec from tag overrides the ones inside.
563 5         9 my $nspec = {%$cspec, %$spec};
564              
565 5 100 33     16 $nspec->{'-prefix'} = "$spec->{'-prefix'}$cspec->{'-prefix'}" if $spec->{'-prefix'} && $cspec->{'-prefix'};
566 5 100 66     10 $nspec->{'-postfix'} = "$cspec->{'-postfix'}$spec->{'-postfix'}" if $spec->{'-postfix'} && $cspec->{'-postfix'};
567              
568 5         9 push @import => [$sym, $nspec];
569             }
570             }
571             else {
572 12         35 push @import => @$cimp;
573             }
574              
575             # New menu
576 15         14 $menu = $newmenu;
577              
578 15         58 next;
579             }
580              
581             # Process the item to figure out what symbols are being touched, if it
582             # is a tag or regex than it can be multiple.
583 157         91 my @list;
584 157 100 66     320 if(ref($arg) eq 'Regexp') {
    100          
585 1         3 @list = sort grep /$arg/, keys %{$menu->{lookup}};
  1         19  
586             }
587             elsif($lead eq '/' && $arg =~ m{^/(.*)/$}) {
588 2         5 my $pattern = $1;
589 2         3 @list = sort grep /$1/, keys %{$menu->{lookup}};
  2         40  
590             }
591             else {
592 154         148 @list = ($arg);
593             }
594              
595             # Normalize list, always have a sigil
596 157 100       124 @list = map {m/^\W/ ? $_ : "\&$_" } @list;
  163         428  
597              
598 157 100       172 if ($exc) {
599 4         17 $exclude{$_} = 1 for @list;
600             }
601             else {
602             $self->croak("Cannot use '-as' to rename multiple symbols included by: $full_arg")
603 153 100 100     248 if $spec->{'-as'} && @list > 1;
604              
605 152         519 push @import => [$_, $spec] for @list;
606             }
607             }
608              
609 44         134 return ($into, \@versions, \%exclude, \@import, $set, $menu);
610             }
611              
612             sub _handle_fail {
613 12     12   22 my $self = shift;
614 12         11 my ($into, $import) = @_;
615              
616 12         15 my $from = $self->from;
617 12         16 my $menu = $self->menu($into);
618              
619             # Historically Exporter would strip the '&' off of sub names passed into export_fail.
620 12 100       47 my @fail = map {my $x = $_->[0]; $x =~ s/^&//; $x} grep $menu->{fail}->{$_->[0]}, @$import or return;
  4         4  
  4         7  
  4         13  
621              
622 3 50       30 my @real_fail = $from->can('export_fail') ? $from->export_fail(@fail) : @fail;
623              
624 3 100       18 if (@real_fail) {
625             $self->carp(qq["$_" is not implemented by the $from module on this architecture])
626 1         7 for @real_fail;
627              
628 1         7 $self->croak("Can't continue after import errors");
629             }
630              
631 2         4 $self->reload_menu($menu);
632 2         5 return;
633             }
634              
635             sub _set_symbols {
636 24     24   3783 my $self = shift;
637 24         764 my ($into, $exclude, $import, $custom_set) = @_;
638              
639 24         37 my $from = $self->from;
640 24         35 my $menu = $self->menu($into);
641 24         40 my $caller = $self->get_caller();
642              
643 6 50 50 7   227 my $set_symbol = $custom_set || eval <<" EOT" || die $@;
  4 50   5   208  
  24         1222  
644             # Inherit the callers warning settings. If they have warnings and we
645             # redefine their subs they will hear about it. If they do not have warnings
646             # on they will not.
647             BEGIN { \${^WARNING_BITS} = \$caller->[9] if defined \$caller->[9] }
648             #line $caller->[2] "$caller->[1]"
649             sub { *{"$into\\::\$_[0]"} = \$_[1] }
650             EOT
651              
652 24         193 for my $set (@$import) {
653 128         156 my ($symbol, $spec) = @$set;
654              
655 128 50       437 my ($sig, $name) = ($symbol =~ m/^(\W)(.*)$/) or die "Invalid symbol: $symbol";
656              
657             # Find the thing we are actually shoving in a new namespace
658 128         139 my $ref = $menu->{exports}->{$symbol};
659 128 100 100     171 $ref ||= $menu->{generate}->($symbol) if $menu->{generate};
660              
661             # Exporter.pm supported listing items in @EXPORT that are not actually
662             # available for export. So if it is listed (lookup) but nothing is
663             # there (!$ref) we simply skip it.
664 128 100 66     197 $self->croak("$from does not export $symbol") unless $ref || $menu->{lookup}->{"${sig}${name}"};
665 127 50       137 next unless $ref;
666              
667 127         103 my $type = ref($ref);
668 127 100       156 $type = 'SCALAR' if $type eq 'REF';
669             $self->croak("Symbol '$sig$name' requested, but reference (" . ref($ref) . ") does not match sigil ($sig)")
670 127 100 66     347 if $ref && $type ne $SIG_TO_SLOT{$sig};
671              
672             # If they directly renamed it then we assume they want it under the new
673             # name, otherwise excludes get kicked. It is useful to be able to
674             # exclude an item in a tag/match where the group has a prefix/postfix.
675 126 100 100     844 next if $exclude->{"${sig}${name}"} && !$spec->{'-as'};
676              
677 123   100     636 my $new_name = join '' => ($spec->{'-prefix'} || '', $spec->{'-as'} || $name, $spec->{'-postfix'} || '');
      66        
      100        
678              
679             # Set the symbol (finally!)
680 123         173 $set_symbol->($new_name, $ref, sig => $sig, symbol => $symbol, into => $into, from => $from, spec => $spec);
681              
682             # The remaining things get skipped with a custom setter
683 123 100       761 next if $custom_set;
684              
685             # Record the import so that we can 'unimport'
686 109 100       148 push @{$IMPORTED{$into}} => $new_name if $sig eq '&';
  102         153  
687              
688             # Apply magic
689 109         93 my $magic = $menu->{magic}->{$symbol};
690 109 100 66     287 $magic ||= $menu->{magic}->{$name} if $sig eq '&';
691 109 100       3763 $from->$magic(into => $into, orig_name => $name, new_name => $new_name, ref => $ref)
692             if $magic;
693             }
694             }
695              
696             ###########################################################################
697             #
698             # The rest of these are utility functions, not methods!
699             #
700              
701             sub _version_check {
702 9     9   3932 my ($mod, $caller, @versions) = @_;
703              
704 9 100       370 eval <<" EOT" or die $@;
705             #line $caller->[2] "$caller->[1]"
706             \$mod->VERSION(\$_) for \@versions;
707             1;
708             EOT
709             }
710              
711             sub _mod_to_file {
712 19     19   1236 my $file = shift;
713 19         68 $file =~ s{::}{/}g;
714 19         27 $file .= '.pm';
715 19         59 return $file;
716             }
717              
718             sub _load_file {
719 9     9   1878 my ($caller, $file) = @_;
720              
721 9 100       587 eval <<" EOT" || die $@;
722             #line $caller->[2] "$caller->[1]"
723             require \$file;
724             EOT
725             }
726              
727              
728             my %HEAVY_VARS = (
729             IMPORTER_MENU => 'CODE', # Origin package has a custom menu
730             EXPORT_FAIL => 'ARRAY', # Origin package has a failure handler
731             EXPORT_GEN => 'HASH', # Origin package has generators
732             EXPORT_ANON => 'HASH', # Origin package has anonymous exports
733             EXPORT_MAGIC => 'HASH', # Origin package has magic to apply post-export
734             );
735              
736             sub optimal_import {
737 20     20 1 1385 my ($from, $into, $caller, @args) = @_;
738              
739 20   100     68 defined(*{"$from\::$_"}{$HEAVY_VARS{$_}}) and return 0 for keys %HEAVY_VARS;
  87         347  
740              
741             # Default to @EXPORT
742 15 100       40 @args = @{"$from\::EXPORT"} unless @args;
  6         27  
743              
744             # Subs will be listed without sigil in %allowed, all others keep sigil
745             my %allowed = map +(substr($_, 0, 1) eq '&' ? substr($_, 1) : $_ => 1),
746 15 100       17 @{"$from\::EXPORT"}, @{"$from\::EXPORT_OK"};
  15         31  
  15         197  
747              
748             # First check if it is allowed, stripping '&' if necessary, which will also
749             # let scalars in, we will deal with those shortly.
750             # If not allowed return 0 (need to do a heavy import)
751             # if it is allowed then see if it has a CODE slot, if so use it, otherwise
752             # we have a symbol that needs heavy due to non-sub, autoload, etc.
753             # This will not allow $foo to import foo() since '$from' still contains the
754             # sigil making it an invalid symbol name in our globref below.
755             my %final = map +(
756             (!ref($_) && ($allowed{$_} || (substr($_, 0, 1, "") eq '&' && $allowed{$_})))
757 15 100 33     106 ? ($_ => *{"$from\::$_"}{CODE} || return 0)
      100        
758             : return 0
759             ), @args;
760              
761 7 50   2   528 eval <<" EOT" || die $@;
  2 50       99  
762             # If the caller has redefine warnings enabled then we want to warn them if
763             # their import redefines things.
764             BEGIN { \${^WARNING_BITS} = \$caller->[9] if defined \$caller->[9] };
765             #line $caller->[2] "$caller->[1]"
766             (*{"$into\\::\$_"} = \$final{\$_}, push \@{\$Importer::IMPORTED{\$into}} => \$_) for keys %final;
767             1;
768             EOT
769             }
770              
771             1;
772              
773             __END__