Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Wondering if there's an easy way to document the names of the subroutines in a perl script, as well as the code that's in them (hopefully in seperate arrays, hashes, etc.) I was thinking that the best way would be to use some sort of debugger/profiler, but if that doesn't work I could do something similiar to:
regex searching for "sub word {"; balanced pattern matching to find the end of the subroutine; continue onwards;
In that case, Regex::Common::balanced or Text::Balanced would come in handy as well as some in depth knowledge of regexes. Any advice as to what course of action I would/could/should take?

Replies are listed 'Best First'.
Re: Profiling Code (Subroutine Documenting.)
by Roger (Parson) on Mar 03, 2004 at 03:48 UTC
    diotalevi has a recursive maximal match regex. I will "steal" that to provided a regex solution :-)
    use strict; use warnings; my $re = qr/ \{ # Opening bracket ((?: # Capture the contents [^}{]+ | (??{$re}) # Or recurse )+) # and allow repeats internally \} # Closing bracket /x; my $str = do { local $/; <DATA> }; while ($str =~ /sub\s+(.*?)\s*?$re/gsi) { print "Subroutine [$1]\n", "=================\n", "{$2}\n\n"; } __DATA__ sub max { my ($a, $b) = @_; return $a > $b ? $a : $b; } sub min { my ($a, $b) = @_; return $a < $b ? $a : $b; }

    And the output -
    Subroutine [max] ================= { my ($a, $b) = @_; return $a > $b ? $a : $b; } Subroutine [min] ================= { my ($a, $b) = @_; return $a < $b ? $a : $b; }

Re: Profiling Code (Subroutine Documenting.)
by BUU (Prior) on Mar 03, 2004 at 03:11 UTC
    All non annonymous subs have an entry in the symbol table. Thus for a list of subs, walk the symbol table and return all the elements that have a code ref. As for getting the code, No idea. One of the B modules might do what you want.
      One of the B modules might do what you want

      Devel::Symdump does this quite handily. For example to print all the subroutines in the symbol table for package Foo do:

      use Devel::Symdump; print "$_\n" foreach Devel::Symdump->functions('Foo');

      Of course - this does ignore any subroutines that arrive via AUTOLOAD.

Re: Profiling Code (Subroutine Documenting.)
by graff (Chancellor) on Mar 03, 2004 at 04:23 UTC
    I wrote something that does this (to a certain extent), and posted it here -- it was originally intended for big apps that are split into multiple source files, but it works fine on a single script.
Re: Profiling Code (Subroutine Documenting.)
by adamk (Chaplain) on Mar 05, 2004 at 02:18 UTC
    Or some sort of solution based on PPI::Tokenizer perhaps?

    Tokenize the perl file and look for any "barewords" after a "sub bareword".