File Coverage

blib/lib/Import/Into/As.pm
Criterion Covered Total %
statement 63 63 100.0
branch 13 14 92.8
condition 1 3 33.3
subroutine 10 10 100.0
pod n/a
total 87 90 96.6


line stmt bran cond sub pod time code
1             package Import::Into::As;
2 1     1   22644 use strict;
  1         2  
  1         26  
3 1     1   6 use warnings;
  1         2  
  1         43  
4              
5             our $VERSION = '0.000002';
6              
7 1     1   2566 use Import::Into;
  1         4351  
  1         43  
8 1     1   7 use Carp qw/croak/;
  1         3  
  1         328  
9              
10             sub import::into::as {
11 4     4   1511 my $class = shift;
12 4         16 my ($target, $rename, @args) = @_;
13              
14             # need to bump level by 2, 1 for the call to _get_imported_syms,
15             # another for the call to import::into
16 4         8 my $bump_level = 1;
17              
18 4         9 my ($dest, $level);
19              
20 4 100       29 if (ref $target) {
    100          
21 2 100       12 $dest = $target->{package} if exists $target->{package};
22 2 100       11 if (exists $target->{level}) {
23 1         3 $level = $target->{level};
24 1   33     11 $dest ||= caller($level);
25 1         7 $target->{level} += $bump_level;
26             }
27             }
28             elsif ($target =~ m/^\d+$/) {
29 1         3 $level = $target;
30 1         4 $dest = caller($level);
31 1         3 $target += $bump_level;
32             }
33             else {
34 1         3 $dest = $target;
35             }
36              
37 4 50       17 croak "unable to find destination package!"
38             unless $dest;
39              
40             # Stash away any current subs with names that conflict iwth new imports
41             # that should be renamed. Also remove them form the namespace so that we
42             # know if a sub gets put into the name that we put it there.
43 4         8 my %old_subs;
44 4         19 for my $name (keys %$rename) {
45 4         44 $old_subs{$name} = $dest->can($name);
46 4         17 _purge_sub($dest, $name);
47             }
48              
49             # Do the import
50 4         25 $class->import::into($target, @args);
51              
52             # Make a copy of all the subs that were imported, keyed by their new names
53 4         1688 my %new_subs = map { $rename->{$_} => $dest->can($_) } keys %$rename;
  4         35  
54              
55             # Restore original subs, purge imported names that should not be kept.
56 4         31 for my $name (keys %$rename) {
57 4         12 my $sub = $old_subs{$name};
58              
59 4 100       15 if ($sub) {
60 1     1   6 no strict 'refs';
  1         2  
  1         46  
61 1     1   5 no warnings 'redefine';
  1         1  
  1         140  
62 2         6 *{"$dest\::$name"} = $sub;
  2         14  
63             }
64             else {
65 2         7 _purge_sub($dest, $name);
66             }
67             }
68              
69             # Put the new subs in place under their new names
70 1     1   5 no strict 'refs';
  1         1  
  1         127  
71 4         26 *{"$dest\::$_"} = $new_subs{$_} for keys %new_subs;
  4         2894  
72             }
73              
74             sub _purge_sub {
75 6     6   17 my ($dest, $name) = @_;
76 1     1   5 no strict 'refs';
  1         1  
  1         243  
77              
78 6         11 local *GLOBCLONE = *{"$dest\::$name"};
  6         33  
79 6         16 my $stash = \%{"${dest}\::"};
  6         25  
80 6         26 delete $stash->{$name};
81 6         19 for my $slot (qw/HASH SCALAR ARRAY IO FORMAT/) {
82 30 100       152 *{"$dest\::$name"} = *GLOBCLONE{$slot} if defined *GLOBCLONE{$slot};
  6         50  
83             }
84             }
85              
86             1;
87              
88              
89             __END__