我正在尝试在perl源文件中找到评论# VERSION
。然后我想在评论之前插入版本(或代替无关紧要)。有谁能用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的正则表达式似乎不正确,另一个是在Comment上使用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
的基础答案 0 :(得分: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');