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