加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

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

发布时间:2020-12-15 21:15:08 所属栏目:大数据 来源:网络整理
导读:与Perl的 eval 相关的常见缺陷是什么,这可能会使您选择使用诸如 Try::Tiny 的模块? 解决方法 Perl的eval有两种口味,即字符串eval和block eval. String eval调用编译器来执行源代码.块eval包围已经编译的代码,可以捕获模块异常. (string 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不会帮助你.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读