perl - Perl die() 调用神秘地没有死
问题描述
在对项目中的一个非常模糊的错误进行了一些认真的调试之后,我能够得到这个简短的代码。一个没有死亡的死亡召唤。
该问题仅在调用时发生script.pl
。如果Class_A
直接调用,则die
调用成功。
我们需要三个文件:
文件 1:script.pl
use strict;
use warnings;
use lib '.';
use Class_A;
# This should not execute. Class_A should die at loading time
print "We shouldn't get here. Class_A shoud not load and die.\n";
文件 2:Class_A.pm
package Class_A;
use strict;
use warnings;
use Class_B;
# This code SHOULD die:
my $p = Class_B->new;
$p->do_something->die_now;
1;
文件 3:Class_B.pm
package Class_B;
use strict;
use warnings;
sub new {
my $class = shift;
bless {}, $class;
}
sub do_something {
my $self = shift;
}
sub die_now {
die "No soup for you!";
}
sub DESTROY {
eval {
1;
};
}
1;
注意到链式调用了at Class_A.pm line 8
吗?好吧,如果你解开它,那么代码就会成功终止。:-|
# This works. There should be no difference.
$p->do_something;
$p->die_now;
而且,最后的惊喜是发现只需删除 eval 调用 at Class_B.pm line 19
,事情就会按预期工作并且脚本会死掉。
我有机会在Perl 5.22.2
,Perl 5.26.1
和Perl 5.32.0
. 另一个惊喜是,这个问题不仅仅发生在5.32.0
。
说真的,WT *?对这里发生的事情有任何想法吗?
解决方案
您发布的代码自 5.28 以来没有出现问题。
该问题与由于异常而发生的展开期间$@
被破坏(使用)有关。eval { }
显然,令人不安的$@
Perl 让 Perl 认为没有发生异常。
根据 perl528delta,$@
现在在所有内容被销毁后设置,这可以防止析构函数破坏$@
. $@
您还可以通过添加来防止析构函数崩溃local $@;
(例如,支持旧版本的 Perl)。
推荐阅读
- eclipse - Git bash 给出错误“SSL 证书问题:无法获取本地颁发者证书”
- r - r中具有多个条件的switch语句
- r - 在数据框中搜索两列
- function - PowerShell ISE 中的 Powershell 函数行为
- julia - 解释 = \ Julia 中的运算符,渐变,速记
- sql - 仅当有足够的记录时才返回结果
- java - Java / LibGDX 缩放问题
- c# - How to update dynamically a textBox with the range when user makes a selection in Excel. C#
- python - Discord.py Rewrite custom errors
- java - 反射 API + 注释:如何发送类继承者作为参数?