简体   繁体   English

Perl无障碍评估

[英]perl eval without block

I am learning perl eval. 我正在学习perl评估。 I understand how to use eval BLOCK, but I have came across the code below. 我知道如何使用eval BLOCK,但是我遇到了下面的代码。 What is the code below doing? 下面的代码在做什么?

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

This reads input, and places it in the variable $_ . 这将读取输入,并将其放置在变量$_ The input used by <> is first @ARGV (if you called your script with arguments), then STDIN (standard input). <>使用的输入首先是@ARGV (如果您使用参数调用脚本),然后是STDIN(标准输入)。

Information on the diamond operator here . 有关钻石运营商的信息,请点击此处

eval; 

This evaluates the line that was read, since not specifying what to evaluate looks at $_ . 这将评估已读取的行,因为未指定要评估的内容会看$_

warn $@ if $@;

This line will display the warnings that appear in $@ , if there are any. 此行将显示$@显示的警告(如果有的话)。

Perl's eval() builtin can take either a BLOCK or an EXPR. Perl的内置eval()可以采用BLOCK或EXPR。 If it is given an EXPR that EXPR will be evaluated as a string which contains Perl code to be executed. 如果给定EXPR,则EXPR将被评估为包含要执行的Perl代码的字符串。

For example: 例如:

#!/usr/bin/env perl

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

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

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

This code executes both say() s as you would expect. 这段代码将执行您期望的两个say()

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

In general the string version of eval() is considered dangerous, especially if you allow interpolation into that string based on variables that are coming from outside your control. 通常, eval()的字符串版本被认为是危险的,特别是如果您允许根据来自控件外部的变量对该字符串进行插值。 For exmaple: 例如:

#!/usr/bin/env perl

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

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

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

This code is safe if called as so: 如果这样调用,此代码是安全的:

$ ./evals.pl Kaoru
Hello, Alex

$ ./evals.pl
Hello, World

But would be very dangerous if the user called it as: 但是,如果用户将其称为:

$ ./evals.pl "Kaoru'; system 'rm -rf /"

On the other hand, in string eval() 's favour, it can be very useful as the opposite of Data::Dumper::Dumper() for turning dumped Perl code back into Perl-internal data structures. 另一方面,在字符串eval()的支持下,它与Data::Dumper::Dumper()相反,对于将转储的Perl代码转换回Perl内部数据结构非常有用。 For example: 例如:

#!/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};

Which, as you would expect, outputs: 如您所料,将输出:

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

See perldoc -f eval or http://perldoc.perl.org/functions/eval.html for more details. 有关更多详细信息,请参见perldoc -f evalhttp://perldoc.perl.org/functions/eval.html

As of Perl 5.16.3, there is also an evalbytes() which treats the string as a byte string rather than a character string. 从Perl 5.16.3开始,还有一个evalbytes()将该字符串视为字节字符串而不是字符串。 See perldoc -f perlunicode or http://perldoc.perl.org/perlunicode.html for more details on the difference between character strings and byte strings. 有关字符串和字节字符串之间差异的更多详细信息,请参见perldoc -f perlunicodehttp://perldoc.perl.org/perlunicode.html

The code which you asked about explicitly: 您明确询问的代码:

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

Is reading in each line of either STDIN or the files specified in @ARGV, and evaluating each line of input as a line of Perl code. 正在读取STDIN或@ARGV中指定的文件的每一行,并将每一行输入评估为Perl代码行。 If that Perl code fails to compile, or throws an exception via die() , the error is warned to STDERR . 如果该Perl代码无法编译,或通过die()引发异常,则将错误警告给STDERR perldoc -f eval has the full details of how and why eval() might set $@ . perldoc -f eval提供了有关eval()如何以及为什么设置$@的全部详细信息。

As an example of the code being called: 作为被调用代码的示例:

$ 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.

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM