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