Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
什么';在Perl中捕捉信号最优雅的方式是什么?_Perl_Exception_Signals - Fatal编程技术网

什么';在Perl中捕捉信号最优雅的方式是什么?

什么';在Perl中捕捉信号最优雅的方式是什么?,perl,exception,signals,Perl,Exception,Signals,我在一个Perl脚本中有两行相邻的代码,可以抛出一个\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。如果第一个抛出,那么我只想从函数返回,而不是尝试继续 我知道如何在两行之前设置处理程序,以便报告错误等: local $SIG{__WARN__} = sub { my $e = shift; # log the error etc. return; }; # possibly warning-resulting line 1 # possibly wa

我在一个Perl脚本中有两行相邻的代码,可以抛出一个
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
。如果第一个抛出,那么我只想从函数返回,而不是尝试继续

我知道如何在两行之前设置处理程序,以便报告错误等:

local $SIG{__WARN__} = sub {
  my $e = shift;
  # log the error etc.
  return;
};
# possibly warning-resulting line 1
# possibly warning-resulting line 2
但这两条线都会发生。我宁愿它只捕获第一个实例并从函数返回。但该处理程序中的返回只返回处理程序,而不返回外部函数


处理信号时,有没有办法从函数返回?

没有,您不能强制调用方返回。(好吧,我相信你可以,用正确的黑魔法XS咒语。但是不要!)


这似乎是一个误导性的设计;警告不应该是致命错误,当然也不应该这样使用。

只要抛出一个异常,捕获并返回调用方即可

使处理程序返回一个值,并在eval之后的if语句中检查它是否返回

实际上,您甚至不必从处理程序返回值,因为它不决定是否返回——您总是在捕获时返回

具体而言:

# We're in the caller now
eval{
    local $SIG{__WARN__} = sub {
        my $e = shift;
        # log the error etc.
        die MyWarnException->new("This is an exception.");
    };

    # Offending statements go here
    do_things();

};
if( $@ && $@->isa('MyWarnException')){
    return;
}
您可以在处理程序中使用die()并在eval中捕获它,如下所示:

use 5.12.0;

local $SIG{__WARN__} = sub {
  my $e = shift;
  # log the error etc.
  die "$e";
};

func(undef);
func('honk');

sub func {
    my $foo = shift;

    eval {
       my $bar = "a $foo";
       say "$bar";
    };
    if ($@) {
       die $@ unless $@ =~ /^Use of uninitialized value/;
    }
    return;
}
不过,您可能希望直接检查警告是否会发生,然后简单地返回:

sub func {
  my $foo = shift;
  return unless defined($foo);
  ...; # use $foo fine
}

将这两行包装在单独的函数中,并让第一行返回一个状态,指示调用函数应该返回。单独的函数可以根据需要处理警告-可能使用相同的函数执行相同的日志记录

sub wrap_line_1
{
    local $SIG{__WARN__} = ...;
    ...do line 1...
    return ($warning_fired ? 1 : 0);
}

sub wrap_line_2
{
    local $SIG{__WARN__} = ...;
    ...do line 2...
    return;
}


...calling code...
wrap_line_1() and return;
wrap_line_2();
...

那么,你的意思是,让处理程序设置一个全局标志,然后在随后的代码中,检查是否设置了该标志?实际上,我太仓促地纠正了自己:你确实需要抛出一个异常。让我编辑答案来说明我的意思。你甚至可以在没有黑魔法的情况下用
使用warnings FATAL=>“all”
。用它,任何警告投掷和异常都可以被相应地处理。公平地说,尽管我很犹豫地认为这是一个“回报”。有关此程序结构的更多信息将很有帮助。您希望收到什么样的警告?如果您从一开始就知道警告的原因,为什么不在执行第1行和第2行之前在sub中说明它?