如何最好地动态准备和运行用户提供的Perl操作符
上下文: Perl脚本根据用户提供的参数文件进行自身初始化,然后对用户提供的源文件进行操作,以过滤数据并执行其他操作 param文件文件包含部分perl表达式,稍后假定在运行时对其进行如何最好地动态准备和运行用户提供的Perl操作符,perl,dynamic,eval,Perl,Dynamic,Eval,上下文: Perl脚本根据用户提供的参数文件进行自身初始化,然后对用户提供的源文件进行操作,以过滤数据并执行其他操作 param文件文件包含部分perl表达式,稍后假定在运行时对其进行evaled,例如: 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
eval
ed,例如:
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将从用户那里获取匹配运算符,然后需要根据其他参数从源文件中筛选出(或输入)记录
一种简单的方法是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;
}
...
我正在考虑进行散列查找,但不知道如何进行。(我也不知道),也想到了闭包
我正在寻找最好、最有效的方法?使用
eval EXPR
:
$match =~ /^(?:[=!][~=]|eq|ne)\z/
or die("Unrecognized operator \"$match\"\n");
my $rv;
eval("\$rv = \$value $match \$operand; 1")
or die $@;
使用分派表:
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);
我看不出闭包有什么用处。使用
eval EXPR
:
$match =~ /^(?:[=!][~=]|eq|ne)\z/
or die("Unrecognized operator \"$match\"\n");
my $rv;
eval("\$rv = \$value $match \$operand; 1")
or die $@;
使用分派表:
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);
我看不出闭包有什么用处。使用
eval
是最少需要维护的代码。请参阅和了解加速评估的相关信息。我不确定是否有理由使用/o
。在这里使用它毫无意义。@ikegami我在/o
感谢上看到使用eval
是最少需要维护的代码。请参阅和了解加速评估的相关信息。我不确定是否有理由使用/o
。在这里使用它毫无意义。@ikegami我在/o
上看到了,谢谢