| 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__ |