Extracting exported variables from a module
Here is a routine from a module I made to extract the variables from a module so they can be put into Perl documentation:
=head2 extract_vars
extract_vars ('Moby', \%vars);
Extract all the exported variables from the specified module, so if
Moby exports C<$data_dir> then
$vars{data_dir} = $Moby::data_dir
This examines C<@EXPORT_OK> in Moby to get the list of variables, and
also evaluates Moby. It assumes that it is being run from a
F<make-pod.pl> which is situated such that Moby is in F<lib/Moby.pm>.
Thus this is strongly dependent on a specific file layout.
Use
extract_vars ($pm, \%vars, verbose => 1);
for debugging.
=cut
sub extract_vars
{
my ($module, $vars, %options) = @_;
if ($module =~ m!/!) {
warn "$module looks wrong; use \$info->{colon} not \$info->{pm}";
}
my $verbose = $options{verbose};
if ($verbose) {
print "Module is $module.\n";
}
my $evals = "use lib \"$Bin/lib\";use $module ':all';";
if ($verbose) {
print "Evaling '$evals'.\n";
}
eval $evals;
if ($verbose) {
print "Getting exports from $module.\n";
}
my @exports = get_exports ($module);
for my $var (@exports) {
if ($var =~ /\$(.*)/) {
if ($verbose) {
print "Adding $var to variables.\n";
}
my $nodollar = $1;
$vars->{$nodollar} = eval "\$$module::$nodollar";
}
elsif ($var =~ /((\@|\%)(.*))/) {
my $variable = $1;
my $sigil = $2;
my $nosigil = $3;
my $export = "\\$sigil$module::$nosigil";
if ($verbose) {
print "Adding $variable as $export.\n";
}
$vars->{$nosigil} = eval $export;
}
}
}
The documentation is generated from a script called "make-pod.pl" in the top directory using the template toolkit.
The routine "get_exports" here looks like this:
# Helper to get exported variables.
sub get_exports
{
my ($module) = @_;
my @exports;
eval "use lib \"$Bin/lib\";use $module ':all';\@exports = \@${module}::EXPORT_OK";
if ($@) {
croak $@;
}
return @exports;
}
Leave a comment