你如何从REPL或调试器中检索方法的POD?

时间:2011-01-18 23:12:59

标签: perl

我希望能够在REPL或debuger中使用它时看到方法/函数的文档。

是否有任何模块可以让您在使用REPL或debuger时查看函数的文档?

显然,如果该模块存在,它会要求您使用可解析结构的POD和代码来提取文档。这不是问题,因为我记录了所有代码,我可以适应任何需要的东西。目前我的所有方法都有一个带有=head2 method_name的前一个POD,以及名称,用法,示例,参数,返回,exeptions等的典型行

典型的例子是当你在debuger(或REPL)中并且你想使用一个函数并且你不记得参数的顺序或它们的类型,或者返回元素的类型或者你想要一个提示用法。

我想要像get_pod($ moudle_bar,$ method_foo)这样的东西,或者甚至能够将get_pod放在基本模块中并且能够说出$bar->get_pod('foo')。我知道这不是微不足道的,并且有很多极端情况。这就是我询问方法-POD提取器模块的原因。

我想在REPL或debuger中显示输出,因此任何指向浏览器中锚定的html-pod的指针对我来说都不方便。

可能有更简单的东西,我被混淆了。

我的第一个蛮力和昂贵的方法:

> $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'

显然这是有效的,因为我知道我的方法描述POD中没有任何空行,所以我在正则表达式中使用.*?)\n\n来捕获方法POD的其余部分。

有人对此任务有任何好的建议或建议吗?

更新

按照 snoopy 的建议,我看了一下Pod :: Coverage源代码,发现Pod :: Coverage :: Extractor(Pod :: Coverage文件中的一个包)有查找Pods Item或head元素并提取它们的方法command。我将看看如何检索这些项目。

# 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;
        }
    }

更新2

从哪里获取信息的另一个地方是pdoc。此脚本生成用于浏览API的html,我在EnsemblBioPerl中使用它。我相信我会学到一些阅读源代码的东西。

2 个答案:

答案 0 :(得分:1)

我也可以找到任何你想要的CPAN模块。

我想知道你是否能以某种方式结合Pod::CoveragePod::Select

Pod :: Coverage可让您获得如下符号:

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
};

然后可以使用Pod :: Select(或类似)来提取相关部分吗?

编辑或者可能是子类/修改Pod :: Coverage以收集正文和符号。

答案 1 :(得分:1)

PDL的交互式shell(perldl)允许read PDL's docs使用???命令,也许可以为REPL做这样的事情