曲径通幽论坛

标题: eval -- 计算表达式值, $@ 变量记录 eval 错误信息 [打印本页]

作者: beyes    时间: 2011-10-21 11:49
标题: eval -- 计算表达式值, $@ 变量记录 eval 错误信息
eval 函数用来计算表达式的值,它常用于捕捉错误和处理异常。位于 eval 之后的语句块是作为单独的 Perl 程序来处理和解析的,其中的所有变量设置,子例程以及格式定义都将保持到 eval 执行完毕。

eval 的返回值是上一个表达式的值,如果出现编译错误,运行时错误,或者执行了 die 语句,那么返回未定义值,并将错误消息记录到 $@ 特殊变量中。如果一切正常,那么 $@ 的内容是空的字符串。


测试代码1,使用 eval 对表达式求值
[code=perl]#!/usr/bin/perl


print "> ";


while (<STDIN>) {
        $result = eval;      # eval 后不接任何东西则默认的处理对象是 $_
        warn $@ if $@;   # 如果 $@ 不为空则表示 $_ 中有出错信息
        print "$result\n" if $result;   #一切正常,打印结果
        print "> ";   #继续下一轮输入测试
}[/mw_shl_code]
运行输出:
$ ./eval.pl
> hello
hello
> 5/2
2.5
> 3*6+10
28
> 10/0                    #除法出错
Illegal division by zero at (eval 4) line 1, <STDIN> line 4.
> "OK                   #输入字符串出错
Can't find string terminator '"' anywhere before EOF at (eval 5) line 1, <STDIN> line 5.
> exit

测试代码2,使用 eval 捕捉程序中的错误
[code=perl]#!/usr/bin/perl


print "Input a number: ";
chop ($a = <STDIN>);


print "Input a divisor: ";
chop ($b = <STDIN>);


eval { $answer = $a/$b; };


warn $@ if $@;     #可以捕捉到除法的错误执行


printf "Division of %.2f by %.2f is %.2f.\n", $a, $b, $answer if $answer;


print "I am here now\n";
[/mw_shl_code]
运行输出:
$ ./eval2.pl
Input a number: 100
Input a divisor: 2
Division of 100.00 by 2.00 is 50.00.
I am here now

$ ./eval2.plInput a number: 100
Input a divisor: 0Illegal division by zero at ./eval2.pl line 12, <STDIN> line 2.
I am here now

作者: beyes    时间: 2011-10-23 14:58
标题: 几种形式: eval $x; eval &quot;$x&quot;; eval &#39;$x&#39;; ev
有几种形式的 eval 的执行方式: eval $x; eval "$x"; eval '$x'; eval { $x };

其中  eval $x; 和 eval "$x"; 的行为一样, 它只是简单的测试了 $x 的值,而不会去改变它,但在某些写法上会有点不同。比如:
[code=perl]
#!/usr/bin/perl

$x = 100;

eval $x++;
print "$x\\n";

eval "$x = $x + 5";
print "$x\\n";[/mw_shl_code]
运行输出:
$ ./eval.pl
101
101
注意,eval $x++; 中并不是由于 eval 函数改变了 $x 的值,而是在执行完 eval 后 $x 的值自行增加了 1,相同的 ++$x 也是在执行 eval 执行之前先自行增加了 $x 的值。从第 2 句的 eval "$x = $x + 5"; 可以看到,我们并没有改变 $x 的值,也就是说,双引号的运算并没有起到改变 $x 的作用。

如果要改变 $x 的值,我们可以使用 eval "$x"; 和 eval '$x'; eval { $x }; 这两种形式,它们的行为类似,比如:
[code=perl]#!/usr/bin/perl

$x = 100;

eval $x++;
print "$x\\n";

eval "$x = $x + 5";
print "$x\\n";

eval '$x = $x + 6';
print "$x\\n";

eval { $x = $x - 4 };
print "$x\\n";[/mw_shl_code]
运行输出:
$ ./eval.pl
101
101
107
103

作者: beyes    时间: 2011-10-23 17:31
标题: 在 eval 中使用符号引用
符号引用有如 $$x++; 这种形式,这种形式是通过一个变量引用另一个变量,如:
[code=perl]#!/usr/bin/perl

$start = "hello";
$hello = "world";

print "$$start\\n";[/mw_shl_code]
运行输出:
[quoute]$ perl temp.pl
world[/quote]

上面的符号引用方式放在 eval 函数里需要在前面添加一个反斜杠。考虑下面代码:
[code=perl]#!/usr/bin/perl

$start = "hello";
$hello = "world";

print "$$start\\n";

$$start = "perl";
print "$hello\\n";

eval "\\$$start = 'china'";
print "$hello\\n";
[/mw_shl_code]
运行输出:
$ perl temp.pl
world
perl
china
在上面程序中,在 eval 函数里使用符号引用时的反斜线不能省略,否则引用失败。




欢迎光临 曲径通幽论坛 (http://www.groad.net/bbs/) Powered by Discuz! X3.2