首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Perl eval块(嵌套eval ?)

Perl eval块(嵌套eval ?)
EN

Stack Overflow用户
提问于 2018-10-08 22:22:25
回答 2查看 466关注 0票数 1

基于某些条件,我在if elsif else中执行一些命令,并将返回代码存储为$status。

代码语言:javascript
复制
eval {
    if ($condition1)
    {
      $status = system ...
    }
    elsif ($condition2)
    {
      foreach my $scenario (@setting) {
         next unless $scenario;
         $status = system <somecommand> 
         }
    }
    elsif ($condition3)
    {
      $status = system ...
    }
    else
    {
      $status = system ...
    }
};
die $@ if $@;
return ($status !=0);

我需要处理下面的代码,因为这有时会在某些情况下失败,所以我不希望程序在中途完全中止并继续运行。我该怎么处理这件事?

代码语言:javascript
复制
elsif ($condition2)
{
  foreach my $scenario (@setting) {
     next unless $scenario;
     $status = system <somecommand> 
     }
}
EN

回答 2

Stack Overflow用户

发布于 2018-10-09 05:15:35

eval的块形式是用于处理Perl语言中的“异常”的内置机制,也就是die

因此,“嵌套”它是很自然的,因为每个级别都可以有自己的。

代码语言:javascript
复制
eval { func(...) }; if ($@) { ... }

sub func {
    ...
    eval { func_lower(...) };
    if ($@) {
        # handle it: recover or re-throw for the higher-level handlers
    }
    ...
}

sub func_lower {
    ...
    eval { func_lower_yet(...) };
    if ($@) {
        # handle it: recover or re-throw for the higher-level handlers
    }
    ...
}

因此,在每个级别都可以决定是否可以解决异常行为,如果不能,则重新抛出(再次发出die ),因为更高的级别可能会得到更好的通知来处理它。

Perl中的异常也会“冒泡”,因此如果某个异常在某一层未被捕获,它将向上传播到调用堆栈中,而上一层仍然可以处理它(直到顶层遇到它不处理的异常,程序才会终止)。

这种典型的嵌套调用结构在if-elsif序列中有点挤,但它仍然适用

代码语言:javascript
复制
eval {
    if    ($condition1) { ... }
    elsif ($condition2) { 
        eval {
            ...
        };
        if ($@) {
            # issue a warning, perhaps set some flag, and continue 
            # or throw a die for the higher-level eval 
        }
    }
    elsif ...
};
if ($@) {
    # interrogate details
}

通过这种方式,您可以将异常与$condition2分支中的代码隔离(捕获),并在if ($@) { ... }部分中处理它们,这样它们就不必触发外部eval (除非该处理程序决定重新抛出)。另请参阅$@ variable

虽然我将elsif ($condition2)分支中的所有代码都封装在一个eval中,但为了盲目地阻止在整个代码段中引发的任何异常并“保护”更高的范围,我们可以(并且确实)将这些eval更精确地放在可能具有攻击性的代码周围。

代码语言:javascript
复制
elsif ($condition2) { 
    foreach my $scenario (@setting) {
        ...
        eval {
            # code-that-may-die
        };
        if ($@) { 
            # handle error, or just report/print it and skip 
        }
        ...
    }
}

一旦代码段(或语句)周围出现eval,它的异常就会停止,代码可以继续执行(例如,即使在发生这种情况的循环中也是如此)。

请注意,您可以从die“抛出”对象,例如,您可以编写一个简单的类来组合您的需求,这为处理程序提供了更大的灵活性。还请注意,CPAN上有用于所有这些功能的模块。

票数 3
EN

Stack Overflow用户

发布于 2018-10-08 22:49:41

代码语言:javascript
复制
die $@ if $@;

如果eval块中出现错误,则通知您的程序中止。如果您删除这一行,它应该可以。

删除后,您可以将最后一行替换为以下内容:

代码语言:javascript
复制
return $@ ? 'something went wrong' : $status;

如果您仍然希望在不停止一切的情况下检测是否出现错误,但这不是强制性的

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52704375

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档