使用Perl的eval时常见的陷阱是什么?

前端之家收集整理的这篇文章主要介绍了使用Perl的eval时常见的陷阱是什么?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
与Perl的 eval相关的常见缺陷是什么,这可能会使您选择使用诸如 Try::Tiny的模块?

解决方法

Perl的eval有两种口味,即字符串eval和block eval. String eval调用编译器来执行源代码.块eval包围已经编译的代码,可以捕获模块异常. (string eval也捕获模块异常以及任何编译错误).

Try :: Tiny仅适用于eval的块形式,但以下内容适用于这两种形式.

每次调用eval它都会改变$@的值.如果eval成功或者eval所捕获的错误,它将是“’”

这意味着您随时调用eval,您将清除以前的任何错误消息. Try :: Tiny为您定制$@变量,以便成功的eval不会清除以前失败的eval的消息.

另一个陷阱来自使用$@作为检查来确定eval是否成功.一个常见的模式是:

eval {...};
if ($@) {
   # deal with error here
}

这依赖于两个假设,首先,任何错误消息$@可以包含是一个真实值(通常为true),并且eval块和if语句之间没有代码.

当然,后者是真实的,但是如果eval块创建了一个对象,并且该eval在eval失败后超出了该范围,则该对象的DESTROY方法将在if语句之前被调用.如果DESTROY碰巧调用eval而不本地化$@并且成功,那么在运行if语句的时候,$@变量将被清除.

解决这些问题的方法是:

my $return = do {
    local $@;
    my $ret;
    eval {$ret = this_could_fail(); 1} or die "eval Failed: $@";
    $ret
};

打破这一行逐行,本地$@为do块创建一个新的$@,这阻止了以前的值的颠覆.我的$ret将是评估代码的返回值.在eval块中,$ret被分配给,然后块返回1.这样,无论什么,如果eval成功,它将返回true,如果失败,它将返回false.在失败的情况下,由你自己决定.上面的代码只是死了,但你可以很容易地使用eval块的返回值来决定运行其他代码.

由于上述咒语有点乏味,容易出错.使用像Try :: Tiny这样的模块可以使您免受这些潜在的错误,每个eval都需要多一些函数调用.知道如何正确地使用eval是很重要的,因为如果你必须使用字符串eval,Try :: Tiny不会帮助你.

猜你在找的Perl相关文章