Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/9.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 - Fatal编程技术网

如何在Perl中捕获并重新显示错误?

如何在Perl中捕获并重新显示错误?,perl,Perl,假设我有一个模块栏,它是模块Foo的子类包装器。我希望调用Bar的方法来完全模仿Foo的方法,甚至是致命的错误。到目前为止,很容易;我只是调用超级方法 sub stuff { # Do stuff here SUPER::stuff(@_); # Do more stuff here } 但是,假设我想捕获、记录并重新显示任何致命错误SUPER::stuff()产生的错误。前两个步骤很简单: sub stuff { # Do stuff here

假设我有一个模块栏,它是模块Foo的子类包装器。我希望调用Bar的方法来完全模仿Foo的方法,甚至是致命的错误。到目前为止,很容易;我只是调用超级方法


sub stuff {
    # Do stuff here

    SUPER::stuff(@_);

    # Do more stuff here
}
但是,假设我想捕获、记录并重新显示任何致命错误
SUPER::stuff()
产生的错误。前两个步骤很简单:


sub stuff {
    # Do stuff here

    eval {
        SUPER::stuff(@_);
    };
    $@ and log("Naughty, naughty: $@");

    # Do more stuff here
}

。。。但我不知道最后一部分怎么做。如何以调用方无法区分调用
Foo->stuff()
和调用
Bar->stuff()
的方式重新抛出错误?我可以在log语句后插入
die$@
并期望它做我想做的事情吗?或者这里有可能让我陷入麻烦的细微差别吗?

你的建议会奏效。Perl没有结构化异常,因此调用程序无论如何只能得到
$@
中的数据

在Perl中安全评估/catch/log/rethrow的完整代码可能有点冗长

 eval {
        SUPER::stuff(@_);
    };
    $@ and ( log("Naughty, naughty: $@"), die $@ );
sub stuff {
    # Do stuff here

    local $@; # don't reset $@ for our caller.
    my $eval_ok = eval { # get the return from eval, it will be undef if the eval catches an error.
        SUPER::stuff(@_);
        1; # return 1 (true) if there are no errors caught.
    };
    if (!$eval_ok) { # don't trust $@ it might have been reset as the eval unrolled.
        my $error = $@ || 'unknown error'; # copy $@ incase write_log resets $@, or is later changed to cause it to reset $@.
        write_log("Naughty, naughty: $error");
        die $error; # after all that we can rethrow our error.
    }

    # Do more stuff here
}
您可以使用sugested by mob来简化:

sub stuff {
    # Do stuff here

    try {
        SUPER::stuff(@_);
    } catch {
        my $error = $_;
        write_log("Naughty, naughty: $error");
        die $error;
    }

    # Do more stuff here
}

避免在
eval
之后使用检查
$@
,尤其是在OO代码中。看到@tchrist,我同意,但我也看到
$@
在生产代码中出现
eval
错误后被重置。@Ven'Tatsu:你觉得
$
的5.14修复程序解决了这个问题吗?@tchrist,看起来会的。@Ven'Tatsu:我很高兴听到这个消息。我更愿意解决问题,而不是永远解决问题。例如,调用
log
,然后调用
die
,由于
$
的全局性质,您不能相信
log
在传递到
die
之前不会更改或重置
$
中的值。但是
$
可以保存对象,这会给你结构化的异常。@tchrist:但是如果我只是以
$@
作为我的参数,我会丢失任何数据吗?(假设我将
$@
存储到另一个变量,这样它就不会被其他变量覆盖,等等)