2016-02-17 3 views
0

Контекст:Как лучше dynamcially подготовить и выполнение команды поставляется операторы Perl

Perl скрипт инициализируется на основе поставляемого пользовательПары-файл, затем действует на поставляется пользовательsource-file для фильтрации данных и выполнения других операций.

пары-файл файл содержит частичное выражение Perl, которые позже, предполагают, чтобы быть eval ред во время выполнения, например:

match:!~ col:1 operand:1|2|3 
match:=~ col:1 operand:[^123] 
match:=! col:1 operand:^DATE 
match:=~ col:1 operand:^(?:\s|DATE) 
match:-~ col:1 operand:^\s 
match:eq col:7 operand:CA 
match:eq col:7 operand:DI 
match:ne col:1 operand:ACCOUNT 
match:ne col:1 operand:POSITIONS 
match:== col:8 operand:999 
match:!= col:8 operand:999 

Хм, а как о чем-то вроде этого? может быть, позже, но мне нужно, что слишком

match="ne list" '11, 71, 7' 

Короче говоря, мой Perl получит оператор матча от пользователя, а затем нужно отфильтровать (или в) записи из исходного файла на основе других Params.

Один и простой подход, является eval:

next unless eval "$value $match $operand"; 

Теперь, учитывая, что я знаю, что $match всегда будет такой же, использование eval на каждом входе источника-файла, звучит как излишество.

if ($match eq '!~') 
{ 
    next unless $value !~ /$operand/o; 
} 
elsif ($match eq '=~') 
{ 
    next unless $value =~ /$operand/o; 
} 
elsif ($match eq 'eq') 
{ 
    next unless $value eq $operand; 
} 
... 

И я думал о поиске хэша, не уверен, как это сделать. (Интересно также об этом), также думая о закрытии ...

Я ищу лучший и самый эффективный подход?

+1

Использование 'eval' - это наименьший код для обслуживания. См. [Eval :: Compile] (http://search.cpan.org/dist/Eval-Compile-0.10/lib/Eval/Compile.pm) и [этот вопрос] (http://stackoverflow.com/questions/ 24911132/perl-speeding-up-eval) об ускорении eval. – Kenney

+2

Я не уверен, что когда-нибудь есть причина использовать '/ o'. Использование здесь здесь не имеет смысла. – ikegami

+0

@ikegami Я вижу [ваш пункт] (http://stackoverflow.com/questions/550258/does-the-o-modifier-for-perl-regular-expressions-still-provide-any-benefit) на '/ o 'спасибо – lzc

ответ

2

Использование eval EXPR:

$match =~ /^(?:[=!][~=]|eq|ne)\z/ 
    or die("Unrecognized operator \"$match\"\n"); 

my $rv; 
eval("\$rv = \$value $match \$operand; 1") 
    or die [email protected]; 

Использование таблицы отправки:

my %ops = (
    '=~' => sub { $_[0] =~ $_[1] }, 
    '!~' => sub { $_[0] !~ $_[1] }, 
    '==' => sub { $_[0] == $_[1] }, 
    '!=' => sub { $_[0] != $_[1] }, 
    'eq' => sub { $_[0] eq $_[1] }, 
    'ne' => sub { $_[0] ne $_[1] }, 
); 

my $op = $ops{$match} 
    or die("Unrecognized operator \"$match\"\n"); 

my $rv = $op->($value, $operand); 

Я не вижу, как замыкания может быть любого использования.

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