我的eval是错误的还是我不理解Perl中的eq vs ==

时间:2015-06-02 18:00:12

标签: perl

我无法理解评估或者我不理解eq vs ==。 我有这个简短的Perl脚本:

[red@tools-dev1 ~]$ cat so.pl
#!/usr/local/bin/perl -w
use strict;

while(<DATA>) {
    chomp;
    my ($arg1, $arg2, $op ) = split /,/;
    if ( $op eq '=' ) {
        $op = 'eq';
    }
    my $cmd = "$arg1 $op $arg2";
    print "[$cmd]\n";
    my $rc = eval $cmd || 0;
    print "rc is [$rc]\n";
}

__DATA__
cat,cat,=

当我执行它时,我得到:

[red@tools-dev1 ~]$ ./so.pl
[cat eq cat]
rc is [0]

有人会认为你得到......

[cat eq cat]
rc is [1]

...因为&#34; cat&#34;等于&#34; cat&#34;,对吧?

5 个答案:

答案 0 :(得分:8)

其他人已经指出了问题的根源。我建议你为此避免使用字符串eval。相反,您可以使用查找表:

#!/usr/bin/env perl

use strict;
use warnings;

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

while(my $test = <DATA>) {
    next unless $test =~ /\S/;
    $test =~ s/\s+\z//;
    my ($arg1, $arg2, $op ) = split /,/, $test;
    if ($ops{$op}->($arg1, $arg2)) {
        print "'$arg1' $op '$arg2' is true\n";
    }
}
__DATA__
cat,cat,=

答案 1 :(得分:7)

您在严格模式下使用裸字,这是一个错误:

$ perl -e 'use strict; cat eq cat'
Bareword "cat" not allowed while "strict subs" in use at -e line 1.
Bareword "cat" not allowed while "strict subs" in use at -e line 1.
Execution of -e aborted due to compilation errors.

每当你eval一个字符串时,你应该检查$@以查看是否有错误。

答案 2 :(得分:3)

你有裸词,而不是字符串,因此你必须将它们作为变量进行比较。

my $cmd = qq{\$arg1 $op \$arg2};

而不是eval,请考虑使用函数

my %f = (
  "eq" => sub { my ($x, $y) = @_; $x eq $y },
  "==" => sub { my ($x, $y) = @_; $x == $y },
  # ..
);
# ..
$f{$op} or die "unknown $op";
my $rc = $f{$op}->($arg1, $arg2);

答案 3 :(得分:3)

你想要

my $cmd = "\$arg1 $op \$arg2";

这将分配字符串

$arg1 eq $arg2

$cmd而不是

cat eq cat

use strict;下是非法的。如果您检查了eval抓住的异常($@),您就会知道这一点。

但你为什么要使用eval

my $rc;
if ($op eq '=') {
   $rc = $arg1 == $arg2;
} else {
   $rc = $arg1 eq $arg2;
}

甚至

my $rc = $op eq '=' ? $arg1 == $arg2 : $arg1 eq $arg2;

如果您实际上有两个以上的操作,则可能需要使用调度表。

答案 4 :(得分:0)

嗯..我真的不明白你的脚本需要什么。但是你的eval表达式实际上被用于:

eval cat eq cat || 0;

完全没有任何意义。

如果您要比较$ arg1是否与$ arg2相同,为什么不直接进行?

$ RC = 0; $ rc = 1 if($ arg1 eq $ arg2);