App-perlimports
view release on metacpan or search on metacpan
lib/App/perlimports/ExportInspector.pm view on Meta::CPAN
# Specifically for File::chdir, which exports a typeglob, but doesn't
# implement every possibility.
for my $key ( keys %hash ) {
if ( substr( $key, 0, 1 ) eq '*' ) {
my $thing = substr( $key, 1 );
for my $sigil ( '&', '$', '@', '%' ) {
my $symbol_name = $sigil . $pkg . '::' . $thing;
if ( Symbol::Get::get($symbol_name) ) {
$hash{ $sigil . $thing } = $key;
}
}
}
}
# Treat Moose type libraries a bit differently. Importing ArrayRef, for
# instance, also imports is_ArrayRef and to_ArrayRef (if a coercion)
# exists. So, let's deal with that here.
if ( $self->is_moose_type_class ) {
for my $key ( keys %hash ) {
if ( $key =~ m{^(is_|to_)} ) {
$hash{$key} = substr( $key, 3 );
}
}
}
return \%hash;
}
sub _build_implicit {
my $self = shift;
my $module_name = $self->_module_name;
my $pkg = $self->_pkg_for_implicit;
my $use_statement = "use $module_name;";
my ( $maybe_exports, $fatal_error )
= $self->_exports_for_include( $pkg, $use_statement );
no strict 'refs';
my $aggregated = {
class_isa => [ @{ $self->_module_name . '::ISA' } ],
export => [ @{ $self->_module_name . '::EXPORT' } ],
export_fail => [ @{ $self->_module_name . '::EXPORT_FAIL' } ],
export_ok => [ @{ $self->_module_name . '::EXPORT_OK' } ],
export_tags => [ @{ $self->_module_name . '::EXPORT_TAGS' } ],
fatal_error => $fatal_error,
_maybe_exports => $maybe_exports,
};
return $aggregated;
}
sub _exports_for_include {
my $self = shift;
my $pkg = shift;
my $use_statement = shift;
my $logger = $self->logger;
# If you're importing Moose into a namespace and following that with an
# import of namespace::autoclean, you may find that symbols like "after"
# and "around" are no longer found.
#
# We log available symbols inside the BEGIN block in order to defeat
# namespace::autoclean, which removes symbols from the stash after
# compilation but before runtime. Thanks to Florian Ragwitz for the tip and
# the preceding explanation.
my $to_eval = <<"EOF";
package $pkg;
use Symbol::Get;
$use_statement
our \@__EXPORTABLES;
BEGIN {
\@__EXPORTABLES = Symbol::Get::get_names();
}
1;
EOF
$self->logger->debug($to_eval);
my $logger_cb = sub {
my $msg = shift;
my $level = 'info';
# Mojo classes tend to throw "Can't locate :all.pm in @INC". This is
# expected and shouldn't be raised to the warning level.
if ( $msg =~ qr{Can't locate} && $msg !~ m{\:all\.pm in \@INC} ) {
$level = 'warning';
}
$logger->log(
level => $level,
message => sprintf(
"Problem trying to eval %s\n%s",
$pkg,
$msg,
),
);
};
local $SIG{__WARN__} = $logger_cb;
local $@ = undef;
## no critic (BuiltinFunctions::ProhibitStringyEval)
## no critic (ErrorHandling::RequireCheckingReturnValueOfEval)
eval $to_eval;
if ($@) {
$logger_cb->($@);
return undef, $@;
}
else {
$self->_increment_success_counter;
}
## no critic (TestingAndDebugging::ProhibitNoStrict)
no strict 'refs';
my @export
= grep { $_ !~ m{(?:BEGIN|ISA|__EXPORTABLES)} && $_ !~ m{^__ANON__} }
@{ $pkg . '::__EXPORTABLES' };
use strict;
( run in 0.539 second using v1.01-cache-2.11-cpan-5735350b133 )