如何在Perl eval块中覆盖exit()调用 [英] How to override exit() call in Perl eval block
问题描述
我需要在Perl中 eval
某些代码,该代码有时可能包含 exit()
调用.一个非常简化的示例是:
I need to eval
some code in Perl that might some times contain an exit()
call in it. A very simplified example of this would be:
use strict;
use warnings;
eval "some_function()";
die $@ if $@;
print "Still alive!\n";
sub some_function {
print "Hello from some_function\n";
exit;
}
我从没去过还活着!"因为 exit()
调用.
I never get to "Still alive!" because of the exit()
call.
我尝试在%SIG
中设置一些键(QUIT,STOP,TERM,BREAK等),但这没有用.我还尝试重新定义 CORE :: exit
,但没有成功.
I tried setting some keys in %SIG
(QUIT, STOP, TERM, BREAK, etc) but that didn't work. I also attempted to redefine CORE::exit
with no success.
在评估
时,如何防止 exit()
调用生效?
How can I prevent an exit()
call from being effective when being eval
ed?
推荐答案
您可以覆盖 exit
,但是必须在编译时执行.因此,请使用一个标志来指示覆盖是否处于活动状态.
You can override exit
, but you must do so at compile-time. So use a flag to signal whether the override is active or not.
our $override_exit = 0;
BEGIN {
*CORE::GLOBAL::exit = sub(;$) {
die "EXIT_OVERRIDE\n" if $override_exit;
CORE::exit($_[0] // 0);
};
}
eval {
local $override_exit = 1;
some_function();
};
my $exit_was_called = $@ eq "EXIT_OVERRIDE\n";
die $@ if $@ && !$exit_was_called;
die("Exit called\n") if $exit_was_called;
但是,这会导致意外捕获的异常.因此,让我们改用 last
.
But that creates an exception that might be caught unintentionally. So let's use last
instead.
our $override_exit = 0;
BEGIN {
*CORE::GLOBAL::exit = sub(;$) {
no warnings qw( exiting );
last EXIT_OVERRIDE if $override_exit;
CORE::exit($_[0] // 0);
};
}
my $exit_was_called = 1;
EXIT_OVERRIDE: {
local $override_exit = 1;
eval { some_function() };
die $@ if $@;
$exit_was_called = 0;
}
die("Exit called\n") if $exit_was_called;
请注意, eval BLOCK
用于捕获异常. eval EXPR
用于编译代码.
Note that eval BLOCK
is used to catch exception. eval EXPR
is used to compile code.
这篇关于如何在Perl eval块中覆盖exit()调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!