Reputation: 5279
I'm writing a script to clean up code which implicitly imports modules. I'd like to change instances of use Foo;
to use Foo qw( bar baz );
In order to automate this, I'd like to be able to know what the contents of @Foo::EXPORT
and @Foo::EXPORT_OK
are. I'm trying to do this without using PPI
to start with.
So, given the variable $module_name
, how can I access @EXPORT
and @EXPORT_OK
for that module?
Upvotes: 1
Views: 92
Reputation: 132914
I think you are really asking how you can access a package variable with the name of the package in a variable.
With a "soft" (of "symbolic") reference, you "deference" a string. When Perl sees that's not a reference, it instead uses the package variable it works out from the string value. strict
disallows this, so you have to turn off that portion of its checks:
my $class = 'Foo';
eval "require $class"; # or however you want to load it
my @exports = do {
no strict 'refs';
@{$class . '::' . 'EXPORT'};
};
You've basically done this in your own answers with lots of convenience stuff wrapped around it. Module::Runtime
, for example, is sanity checking the module name and converting it to a filename that it can require
. That's fine, but it obscures the meat of your solution.
You mention PPI but not the reason you don't want to use it. For those of you just joining the party, you can't necessarily tell from static analysis what will be in any Perl variable. I deal with some modules that dynamically build up the export list based on what it defines and what will be available based on some other conditions. That is, @EXPORT
and friends are empty until the end of the unit compilation. That's not something you should do, but it's possible and statically uninspectable.
Upvotes: 2
Reputation: 5279
Thanks to Graham Knop for pointing out the syntax I needed and also for a PerlMonks conversation which covers this: exports -- which module exports are used?
#!/usr/bin/env perl
use strict;
use warnings;
use Data::Printer; # exports p()
use Module::Runtime qw( require_module );
my $module_name = 'POSIX';
require_module( $module_name );
$module_name->import;
no strict 'refs';
p @{$module_name.'::EXPORT'};
p @{$module_name.'::EXPORT_OK'};
Upvotes: 2