Нахождение последнего "}" подпрограммы - PullRequest
2 голосов
/ 12 ноября 2010

Предположим, у меня есть файл с Perl-кодом: кто-нибудь знает, есть ли модуль, который может найти закрывающую "}" определенной подпрограммы в этом файле. Например:

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

routine_one( '{°^°}' );

routine_two();

sub routine_one {
    my $arg = shift;
    if ( $arg =~ /}\z/ ) {
    say "Hello my }";
    }
}

sub routine_two {
    say '...' for 0 .. 10
}

Модуль должен иметь возможность удалить всю рутину_one или он может сообщить мне номер строки закрывающего «}» из этой рутины.

Ответы [ 3 ]

12 голосов
/ 12 ноября 2010

Вы хотите использовать PPI , если собираетесь анализировать Perl-код.

3 голосов
/ 12 ноября 2010
#!/usr/bin/env perl
use warnings;
use 5.012;
use PPI;

my $file = 'Example.pm';

my $doc = PPI::Document->new( $file );
$doc->prune( 'PPI::Token::Pod' );
$doc->prune( 'PPI::Token::Comment' );
my $subs = $doc->find( sub { $_[1]->isa('PPI::Statement::Sub') and $_[1]->name eq 'layout' } );
die if @$subs != 1;

my $new = PPI::Document->new( \qq(sub layout {\n    say "my new layout_code";\n}) );
my $subs_new = $new->find( sub { $_[1]->isa('PPI::Statement::Sub') and $_[1]->name eq 'layout' } );


$subs->[0]->block->insert_before( $subs_new->[0]->block ) or die $!;
$subs->[0]->block->remove or die $!;


# $subs->[0]->replace( $subs_new->[0] );
# The ->replace method has not yet been implemented at /usr/local/lib/perl5/site_perl/5.12.2/PPI/Element.pm line 743.

$doc->save( $file ) or die $!;
0 голосов
/ 12 ноября 2010

Следующее будет работать, если в ваших подпрограммах нет пустых строк, как в вашем примере:

#!/usr/bin/perl -w

use strict;

$^I = ".bkp";  # to create a backup file

{
   local $/ = ""; # one paragraph constitutes one record
   while (<>) {
      unless (/^sub routine_one \{.+\}\s+$/s) {  # 's' => '.' will also match "\n"
         print;
      }
   }
}
...