什么';在Perl中捕捉信号最优雅的方式是什么?
我在一个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
\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中说明它?