Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How could you retrieve a method's POD from inside a REPL or debugger?

Tags:

perl

I would like to be able to see the documentation of a method/function when using it inside REPL or debuger.

Is there any module that allow you to see the documentation of a function when using REPL or a debuger?.

Obviously if that module exist it would ask you to have your POD and code with a parseable structure in order to extract the docs. That is not a problem because I have all my code documented and I can adapt to whatever is needed. Currently I have all my methods with a preceding POD with a =head2 method_name and the typical lines for name, usage, example, args, return, exeptions etc

The typical example is when you are in the debuger (or REPL) and you want to use a function and you don't remember the order of arguments or their types, or the type of the return element or you want a hint for the usage.

I would like to have something like get_pod($moudle_bar, $method_foo), or even better being able to put a get_pod in a base module and being able to say $bar->get_pod('foo'). I know that this is not trivial and has a lot of corner cases. This is the reason that I am asking about a method-POD extractor module.

I want to show the output inside the REPL or debuger so any pointer to an anchored html-pod in a browser is not convenient for me.

It could be that there is something much more simple and I am obfuscated.

My first brute force and expensive approach:

> $self = new MyModule
> m $self # to see the available methods for double check the spelling
> # method wanted '_connect_db'
> $cmd = 'perldoc -t ' . ref($self)
> x qx{$cmd}=~/(_connect_db.*?)\n\n/msg
0  '_connect_db
     Title   : _connect_db
     Usage   :
     Function: create a database conection and return the handler
     Example : $dbh = $self->_connect_db($user, $pass, $db_name) # host is FPrefect by default
     Returns : [0] DBI $dbh object
     Args    :
                [0] $user,
                [1] $pass,
                [2] $db_name,
                [3] $host,
                [4] $db_brand # mysql, sqlite
                [5] $mode = (ro, rw) # not used now. in the future it would use this for read the user and password'

Obviously this works because I know that I don't have any empty lines in my method description PODs so I use .*?)\n\n in the regex to capture the rest of the method POD.

Do someone have any good suggestion or advice for this task?

UPDATE:

Following snoopy suggestions I have taken a look at Pod::Coverage source code and I found that Pod::Coverage::Extractor (a package inside the file for Pod::Coverage) has the method command that look for Pods Item or head elements and extract them. I will take a look how to retrieve this items.

# package Pod::Coverage::Extractor
#extract subnames from a pod stream
sub command {
    my $self = shift;
    my ( $command, $text, $line_num ) = @_;
    if ( $command eq 'item' || $command =~ /^head(?:2|3|4)/ ) {

        # take a closer look
        my @pods = ( $text =~ /\s*([^\s\|,\/]+)/g );
        $self->{recent} = [];

        foreach my $pod (@pods) {
            print "Considering: '$pod'\n" if debug;

            # it's dressed up like a method cal
            $pod =~ /-E<\s*gt\s*>(.*)/ and $pod = $1;
            $pod =~ /->(.*)/           and $pod = $1;

            # it's used as a (bare) fully qualified name
            $pod =~ /\w+(?:::\w+)*::(\w+)/ and $pod = $1;

            # it's wrapped in a pod style B<>
            $pod =~ s/[A-Z]<//g;
            $pod =~ s/>//g;

            # has arguments, or a semicolon
            $pod =~ /(\w+)\s*[;\(]/ and $pod = $1;

            print "Adding: '$pod'\n" if debug;
            push @{ $self->{ $self->{nonwhitespace}
                    ? "recent"
                    : "identifiers" } }, $pod;
        }
    }

UPDATE 2

Another place from where to take info is pdoc. This script generates html for browsing APIs and I use it in Ensembl and BioPerl. I am sure I will learn something reading the source code.

like image 895
Pablo Marin-Garcia Avatar asked Dec 05 '25 16:12

Pablo Marin-Garcia


2 Answers

I also could find any single CPAN module that does exactly want you want.

I wonder if you could somehow combine Pod::Coverage and Pod::Select.

Pod::Coverage lets you get at the symbols as below:

snoopy@deb6:~$ perl -de0
DB<1> use Pod::Coverage
DB<2> our $pc = Pod::Coverage->new(package => 'Mouse');
DB<3> $pc->coverage;
DB<4> use Data::Dumper
DB<5> p Dumper $pc->{symbols}
$VAR1 = {
  'around' => 1,
  'init_meta' => 0,
  'super' => 0,
  'has' => 1,
  'after' => 1,
  'augment' => 0,
  'inner' => 0,
  'override' => 0,
  'with' => 0,
  'extends' => 1,
  'before' => 1
};

Maybe Pod::Select (or Similar) could then be used to extract the relevant sections?

EDIT or maybe subclass/modify Pod::Coverage to gather body text along with the symbols.

like image 174
dwarring Avatar answered Dec 08 '25 08:12

dwarring


PDL's interactive shell (perldl) lets you read PDL's docs with the ? and ?? commands, perhaps something like that can be done for REPL.

like image 35
Joel Berger Avatar answered Dec 08 '25 08:12

Joel Berger



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!