没有块的perl eval

时间:2014-06-08 10:12:04

标签: perl eval

我正在学习perl eval。我理解如何使用eval BLOCK,但我遇到了下面的代码。下面的代码是什么?

while(<>) {
    eval; 
    warn $@ if $@;
}

2 个答案:

答案 0 :(得分:1)

while(<>) {

读取输入,并将其放在变量$_中。 <>使用的输入是@ARGV(如果您使用参数调用脚本),则为STDIN(标准输入)。

有关钻石运营商here的信息。

eval; 

这会评估已读取的行,因为未指定要评估的内容$_

warn $@ if $@;

此行将显示$@中显示的警告(如果有)。

答案 1 :(得分:0)

Perl的eval()内置版可以采用BLOCK或EXPR。如果给出EXPR,则EXPR将被评估为包含要执行的Perl代码的字符串。

例如:

#!/usr/bin/env perl

use strict;
use warnings;
use feature 'say';

eval { say "Hello, Block World!"; };

eval 'say "Hello, String World!";';

此代码按预期执行say()

$ ./evals.pl
Hello, Block World!
Hello, String World!

通常,eval()的字符串版本被认为是危险的,特别是如果您允许基于来自控件外部的变量插入到该字符串中。例如:

#!/usr/bin/env perl

use strict;
use warnings;
use feature 'say';

my $name = $ARGV[0] // 'World';

eval "say 'Hello, $name';";

如果这样调用,此代码是安全的:

$ ./evals.pl Kaoru
Hello, Alex

$ ./evals.pl
Hello, World

但如果用户将其称为:

,则会非常危险
$ ./evals.pl "Kaoru'; system 'rm -rf /"

另一方面,在字符串eval()中,它可以非常有用,因为它将转储的Perl代码转换回Perl内部数据结构,与Data::Dumper::Dumper()相反。例如:

#!/usr/bin/env perl

use strict;
use warnings;
use feature 'say';

use Data::Dumper;

my $hashref = { a => 1, b => 2, c => 3 };

print Dumper $hashref;

my $VAR1;
my $hashref_copy = eval Dumper $hashref;

say $hashref_copy->{b};

正如您所料,输出:

$ ./evals.pl
$VAR1 = {
        'c' => 3,
        'b' => 2,
        'a' => 1
        };
2

有关详细信息,请参阅perldoc -f evalhttp://perldoc.perl.org/functions/eval.html

从Perl 5.16.3开始,还有一个evalbytes()将字符串视为字节字符串而不是字符串。有关字符串和字节字符串之间差异的详细信息,请参阅perldoc -f perlunicodehttp://perldoc.perl.org/perlunicode.html

您明确询问的代码:

while(<>) {
    eval; 
    warn $@ if $@;
}

读取STDIN的每一行或@ARGV中指定的文件,并将每行输入作为一行Perl代码进行评估。如果该Perl代码无法编译,或通过die()引发异常,则会向STDERR发出错误警告。 perldoc -f eval详细了解eval()可能设置$@的方式和原因。

作为被调用代码的一个例子:

$ echo 'print "foo\\n";' | ./evals.pl 
foo

$ echo 'print 1 + 1, "\\n";' | ./evals.pl
2

$ echo 'dfsdfsdaf' | ./evals.pl
Bareword "dfsdfsdaf" not allowed while "strict subs" in use at (eval 1) line 1, <> line 1.

$ echo 'die "dead";' | ./evals.pl 
dead at (eval 1) line 1, <> line 1.