Perl评估模块(嵌套评估)?

时间:2018-10-08 14:22:25

标签: perl

如果是elsif else,我会根据某些条件在其中执行一些命令,并存储返回代码 作为$ status。

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);

我需要处理以下代码,因为在某些情况下有时会失败,所以 我不希望程序在中间完全中止并继续运行。 我该如何处理?

elsif ($condition2)
{
  foreach my $scenario (@setting) {
     next unless $scenario;
     $status = system <somecommand> 
     }
}

2 个答案:

答案 0 :(得分:2)

eval的BLOCK形式是用于处理Perl中的{exception}(即die)的内置机制。

因此,“嵌套”起来很自然,因为每个级别都有自己的

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序列中有点塞满,但仍然适合

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隔离开来,从而不必触发外部eval

请注意,您可以在die中“抛出”对象,例如,编写一个简单的类以汇总您的需求,这为处理程序提供了更大的灵活性。另外请注意,CPAN上有所有模块。

答案 1 :(得分:0)

die $@ if $@;

告诉您的程序如果eval块中出现问题,将中止运行。 如果删除此行,应该没问题。

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

return $@ ? 'something went wrong' : $status;

如果您仍想在不停止所有操作的情况下检测是否出了问题,但这不是强制性的