曲径通幽论坛

 找回密码
 立即注册
搜索
查看: 4450|回复: 2
打印 上一主题 下一主题

eval -- 计算表达式值, $@ 变量记录 eval 错误信息

[复制链接]

4918

主题

5880

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34387
跳转到指定楼层
楼主
发表于 2011-10-21 11:49:37 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
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

4918

主题

5880

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34387
沙发
 楼主| 发表于 2011-10-23 14:58:41 | 只看该作者

几种形式: 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

4918

主题

5880

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34387
板凳
 楼主| 发表于 2011-10-23 17:31:24 | 只看该作者

在 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 函数里使用符号引用时的反斜线不能省略,否则引用失败。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|曲径通幽 ( 琼ICP备11001422号-1|公安备案:46900502000207 )

GMT+8, 2024-5-19 05:18 , Processed in 0.076977 second(s), 21 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表