如何在Perl eval块中覆盖exit()调用 [英] How to override exit() call in Perl eval block

查看:38
本文介绍了如何在Perl eval块中覆盖exit()调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要在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 evaled?

推荐答案

您可以覆盖 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆