oalders
oalders

Reputation: 5279

Dynamically finding @EXPORT and @EXPORT_OK for a loaded module

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

Answers (2)

brian d foy
brian d foy

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

oalders
oalders

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

Related Questions