if语句中的Eval

时间:2010-12-20 16:16:10

标签: perl

如何在perl if语句中动态传递eq或ne?我在下面尝试但是没有工作:

my $this="this";
my $that="that";
my $cond='ne';
if($this eval($cond) $that)
{
  print "$cond\n";
}

3 个答案:

答案 0 :(得分:9)

您不需要eval。只需使用dispatch table

sub test {
    my %op = (
        eq => sub { $_[0] eq $_[1] },
        ne => sub { $_[0] ne $_[1] },
    );
    return $op{ $_[2] }->($_[0], $_[1]);        
}

if (test($this, $that, $cond)){
    print "$cond\n";
}

答案 1 :(得分:7)

if (($cond eq 'eq') xor ($this ne $that)) {
     print $cond;
};

但也许更好更通用的方法是使用perl的功能并创建函数哈希表:

my %compare = (
     eq => sub {shift eq shift},
     ne => sub {shift ne shift},
     lt => sub {shift lt shift},
     like => sub {$_[0] =~ /$_[1]/},
     # ....
);

#...
if ($compare{$cond}->($this, $that)) {
     print $cond;
};

答案 2 :(得分:2)

每当您使用eval生成运行时代码时,最好记住一些细节。首先,eval是危险的,因此您应该eval尽可能最小,最通用的代码,并检查错误。其次,eval很慢,因此您应该将结果存储起来以供日后使用。

{my %cache;
sub compare {
    my ($x, $op, $y) = @_;
    $cache{$op} ||= eval "sub {\$_[0] $op \$_[1]}" || die "bad op: $op\n";
    $cache{$op}->($x, $y)
}}

my $this="this";
my $that="that";
my $cond='ne';

if (compare $this, $cond, $that) {
    print "$cond\n";
}

这里compare函数会在看到一个尚未拥有的运算符时构建一个新的coderef(带eval)。检查eval的返回值,如果出错,则会引发错误。

此coderef(期望其值作为参数)存储在%cache中。然后使用两个值作为参数运行缓存的coderef。只要使用相同的运算符,就会反复使用相同的coderef。