Как мне сказать Perl выполнить кусок сгенерированного кода Perl? - PullRequest
0 голосов
/ 29 марта 2010

Я пытаюсь поймать строку cd /a/b/c и выполнить следующее преобразование (как часть более крупной программы на Perl).

Если существует cd /a/b/c, конвертируйте cd /a/b/c & rarr; chdir '/a/b/c' и выполнить chdir '/a/b/c'

Я могу сделать преобразование; Я не могу сказать perl выполнить мою команду.

Ответы [ 3 ]

3 голосов
/ 29 марта 2010
#!/usr/bin/perl

use strict; use warnings;

while ( my $line = <DATA> ) {
    if ( my ($path) = $line =~ m{^cd \s+ (/? (\w+) (?:/\w+)* )}x ) {
        warn "Path is $path\n";
        chdir $path
            or warn "Cannot chdir to '$path': $!";
    }
}

__DATA__
cd a
cd /a/b/c
cd /a

Выход:

Path is a
Cannot chdir to 'a': No such file or directory at C:\Temp\k.pl line 8,  line 1.
Path is /a/b/c
Cannot chdir to '/a/b/c': No such file or directory at C:\Temp\k.pl line 8,  line 2.
Path is /a
Cannot chdir to '/a': No such file or directory at C:\Temp\k.pl line 8,  line 3.
2 голосов
/ 30 марта 2010

То, что вы действительно хотите, это таблица отправки. Когда вы сталкиваетесь с командой, такой как cd, вы ищете соответствующую подпрограмму в таблице диспетчеризации, где вы сопоставляете действительные команды с кодом, который вы хотите выполнить:

%dispatch = (
     cd => sub { chdir( $_[0] ) }, 
     ...
     );

while( <> )
     {
     my( $command, @args ) = split;
     if( exists $dispatch{ $command } )
          {
          $dispatch{ $command }->(@args);
          }
     }

У меня есть несколько расширенных примеров такого рода вещей в Мастеринг Perl . Приятным моментом является то, что вы не меняете цикл обработки, когда у вас есть новые команды, и вы обрабатываете только те команды, которые намереваетесь обрабатывать. Кроме того, вы можете создать эту таблицу диспетчеризации непосредственно из конфигурации.

1 голос
/ 29 марта 2010

, если каталог, который вы хотите найти, известен заранее.

$str = "blah blah cd /a/b/c blah";
if ( $str =~ /cd \/a\/b\/c/ ){
  print "found\n";
  chdir("/a/b/c");
}
...