是否可以在具有“重载”的 Perl 程序中使用 Try::Tiny $SIG{__DIE__}?例如,这个程序的期望输出是“caught it”:
#!/usr/bin/perl
use strict;
use warnings;
use diagnostics;
use Try::Tiny;
# here how to deal with try and catch
$SIG{__DIE__} =
sub {
print "died my way $_[0]"
};
my $rv;
try {die "its only a flesh wound"; }
catch {
$rv = undef;
print "caught it: $_ ";
};
Run Code Online (Sandbox Code Playgroud)
感谢您的关注和任何建议!
使用$SIG{__DIE__}show的文档$^S是有原因的:您几乎总是希望$^S在__DIE__处理程序中使用来避免您所询问的问题。
例如,
#!/usr/bin/perl
use strict;
use warnings;
use Try::Tiny;
$SIG{__DIE__} = sub {
return if $^S; # If in eval.
print(STDERR "Died: $_[0]"); # Send msg to STDERR, not STDOUT.
exit( $! || ( $? >> 8 ) || 255 ); # Emulate die().
};
try {
die("It's only a flesh wound.");
} catch {
print("Caught: $_");
};
die("More than a flesh wound");
print("done.\n");
Run Code Online (Sandbox Code Playgroud)
产出
Caught: It's only a flesh wound. at a.pl line 14.
Died: More than a flesh wound at a.pl line 19.
Run Code Online (Sandbox Code Playgroud)
Try::Tiny主要是eval调用的语法糖包装器,块die内的eval调用将调用$SIG{__DIE__}处理程序。作者预料到您的反对,但最终决定坚持遗留行为。
尽管可以说
$SIG{__DIE__}应该在eval块内禁用 它,因为人们还没有成长为依赖它。因此,在兼容性的利益,try不会禁用$SIG{__DIE__}的错误代码投掷的范围。
但是你可以自己禁用它
try {
local $SIG{__DIE__};
...
} catch { ... };
Run Code Online (Sandbox Code Playgroud)
或重写try .. catch以做你想做的事。
sub my_try (&;@) {
my ($try, @code_refs) = @_;
local $SIG{__DIE__};
Try::Tiny::try($try,@code_refs);
}
Run Code Online (Sandbox Code Playgroud)