Perl die() 神秘地调用不死
Perl die() call mysteriously not dying
在对项目中的一个非常隐蔽的错误进行一些认真的调试之后,我能够得到这段简短的代码。一个没有死的死亡电话。
该问题仅在调用 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 认为没有发生异常。
根据 perl528delta,$@
现在在所有内容被销毁后设置,这可以防止析构函数破坏 $@
。您还可以通过添加 local $@;
(例如支持旧版本的 Perl)来防止析构函数破坏 $@
。
在对项目中的一个非常隐蔽的错误进行一些认真的调试之后,我能够得到这段简短的代码。一个没有死的死亡电话。
该问题仅在调用 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 认为没有发生异常。
根据 perl528delta,$@
现在在所有内容被销毁后设置,这可以防止析构函数破坏 $@
。您还可以通过添加 local $@;
(例如支持旧版本的 Perl)来防止析构函数破坏 $@
。