前几天做perl程序,偶碰到一串eval脚本,让人大跌眼镜,因为不知道是干嘛的。现有时间,就专门收集了一些资料,发现绝大多数都是英语资料。为了以后能快点上手,故通过分析,code验证,特意归纳如下。
eval EXPR
eval {BLOCK}
这两种方法都能达到catch exception的效果,并把错误信息保存到$@中。区别是方法一是执行过程中报错而方法二是在编译过程中报错。
# make divide-by-zero nonfatal
eval { $answer = $a / $b; }; warn $@ if $@;
# same thing, but less efficient eval '$answer = $a / $b'; warn $@ if $@;
# a compile-time error eval { $answer = }; # WRONG
# a run-time error eval '$answer ='; # sets $@
使用eval可以对错误信息进行处理,那么,如何在catch到exception后做一些其他的操作呢?perl里面可以通过使用信号来完成这个工作。如
非常简单的做法就是die如下。
# a very private exception trap for divide-by-zero eval { local $SIG{'__DIE__'}; $answer = $a / $b; }; warn $@ if $@;
由此可以进一步推测,是否可以给该信号一个sub 呢? 答案是肯定的。
# __DIE__ hooks may modify error messages
{ local $SIG{'__DIE__'} = sub { (my $x = $_[0]) =~ s/foo/bar/g; die $x };
eval { die "foo lives here" };
print $@ if $@; # prints "bar lives here"
}
最后,对eval可能的用法进行一下总结
eval $x; # CASE 1
eval "$x"; # CASE 2
eval '$x'; # CASE 3 eval { $x }; # CASE 4
eval "\$$x++"; # CASE 5 $$x++; # CASE 6
case 1 和case 2功能相同,都是运行$x所包含的代码。case 3 和case 4功能相同,都是运行代码 $x并返回$x的值。case 5 和6是等价的但5不常用。