4

我试图# VERSION在 perl 源文件中找到注释。然后我想在评论之前插入版本(或代替无关紧要)。谁能告诉我用PPI做到这一点的正确方法?

use strict;
use warnings;
package My::Package;
# VERSION
...

use strict;
use warnings;
package My::Package;
our $VERSION = 0.1;# VERSION
...

保持# VERSION最终结果是可选的

我实际上有几个关于如何找到 # VERSION 的想法,但一个是序列化 ppi doc 的正则表达式,看起来不正确,另一个是在评论上使用 find_first 但如果它不是第一个我不确定该怎么办。

更新的代码这似乎更接近正确的解决方案,因为它只查看注释。但我不确定如何使用或真正如何创建新变量。

#!/usr/bin/env perl
use 5.012;
use strict;
use warnings;

use PPI;

my $ppi = PPI::Document->new('test.pm');

my $comments = $ppi->find('PPI::Token::Comment');

my $version = PPI::Statement::Variable->new;

foreach ( @{$comments} ) {
    if ( /^\s*#\s+VERSION\b$/ ) {
        $_->replace($version);
    }
}

更新

这个问题的答案成为了DZP::OurPkgVersion的基础

4

1 回答 1

4

这是一些与您描述的内容类似的代码-无论如何它都会让您入门。它是从Catalyst::Helper::AuthDBIC ( source ) 编辑的,这是一个使用 PPI 的完整示例(尽管它可能不是最佳实践):

sub make_model {
    ### snip some stuff
    my $module = "lib/$user_schema_path.pm";
    my $doc = PPI::Document->new($module);
    my $digest_code = # some code
    my $comments = $doc->find(
        sub { $_[1]->isa('PPI::Token::Comment')}
    );
    my $last_comment = $comments->[$#{$comments}];
    $last_comment->set_content($digest_code);
    $doc->save($module);
}

我想在您的情况下,您获取 $comments arrayref 并修改与 /VERSION/ 匹配的第一项与替换内容。

这是海报的最终代码:

#!/usr/bin/env perl
use 5.012;
use warnings;

use PPI;

my $ppi = PPI::Document->new('test.pm');

my $comments = $ppi->find('PPI::Token::Comment');

my $version = 0.01;

my $_;
foreach ( @{$comments} ) {
    if ( /^(\s*)(#\s+VERSION\b)$/ ) {
        my $code = "$1" . 'our $VERSION = ' . "$version;$2\n";
        $_->set_content("$code");
    }
}
$ppi->save('test1.pm');
于 2010-07-27T23:40:52.833 回答