2010-07-27 3 views
4

Я пытаюсь найти комментарий # VERSION в исходном файле perl. Затем я хочу вставить версию перед комментарием (или вместо нее не имеет значения). Может ли кто-нибудь сказать мне правильный способ сделать это с помощью PPI?Как найти комментарий к PPI, а затем вставить код перед ним?

перед тем

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

после

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

поддержания # VERSION в конечном итоге является необязательным

Я на самом деле есть несколько идей о том, как найти # VERSION, но один является regex сериализованного 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); 
    } 
} 

UPDATE

Ответ на этот вопрос стал основой для DZP::OurPkgVersion

+0

Можете ли вы привести пример до и после? –

+0

пример добавлен в вопрос. – xenoterracide

+0

Похож на новый плагин D :: Z в создании, а? В этом разговоре есть материал PPI в контексте Perl :: Critic: http://renee-baecker.de/talks/FrOSCon2009_PerlCritic.pdf – daxim

ответ

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

Я полагаю, в вашем случае, если вы захватите $ комментарии ссылку на массив и изменить первый элемент, который соответствует/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'); 
+0

спасибо не совсем то, что мне нужно, но этого достаточно, чтобы взять то, что я уже выяснил, и заставить его работать. – xenoterracide

+0

более или менее мой последний код (по крайней мере, для этой части) http://privatepaste.com/21aed62cfa, если вы хотите скопировать его в свой ответ – xenoterracide

 Смежные вопросы

  • Нет связанных вопросов^_^