在工作中,我经过严格的调试才发现了项目中一个非常晦涩难懂的 bug,在这之后,我写出了下面这段简短的代码。其中一个 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;
最后的惊喜是发现仅仅通过删除 Class_B.pm line 19
处的 eval 调用,然后事情就如预期的那样工作并终止了脚本。
我有机会在 Perl 5.22.2
、Perl 5.26.1
和 Perl 5.32.0
中测试了这个问题。令人惊讶的是,这个问题只在 5.32.0
中不存在。
真的,WT*?对此有何想法吗?
.
不是脚本的目录。请使用use FindBin qw( $RealBin ); use lib $RealBin;
。 - ikegami