Ubuntu 12.04.3 LTS Perl 5.14.2
我们在制作中有一个奇怪的错误。 它是100%复制并由固定 对它进行额外的块效应。
在这些情况下重现了错误:
1)eval { <some-code>; <die or Carp::confess>; }
die或Carp :: confess terminate process(eval没有帮助)
如此制作
这像:
eval { eval { <some-code>; <die or Carp::confess>; } $@ && die $@; }
帮助
2)
our %ENV
重置%ENV
所以让eval { our %ENV; }
帮助
我怀疑这个奇怪的案例是因为某些原因 我们的xs-modules,但找不到原因。
欢迎提出任何建议或提示
我无法发布任何代码,因为它在代码库中被深深复制。 简单的1-liners不会重现它。
此外,我注意到问题是通过不包括一些xs-modules来解决的。
P.S。我想这个问题更适合 perl-internals和perl-xs之间的相互作用,而不是pure-perl
答案 0 :(得分:4)
local
内的eval
会在外部恢复。如果局部变量是神奇的并且它的setter死了,你可以看到这种行为。
perl -MVariable::Magic=cast,wizard -le'
cast $x, wizard(
set => sub {
print "store ${$_[0]}";
die "leaked\n" if $i++ && ${$_[0]} == 123;
},
);
$x = 123; eval { local $x = 456; die "meow\n"; 1 } or print("caught");
'
store 123
store
store 456
store 123
leaked
绑定变量是神奇的,因此以下产生相同的输出:
perl -MTie::Scalar -le'
@ISA=Tie::StdScalar::;
sub STORE {
print "store $_[1]";
die "leaked\n" if $i++ && $_[1] == 123;
return shift->SUPER::STORE(@_);
}
tie $x, __PACKAGE__;
$x = 123; eval { local $x = 456; die "meow\n"; 1 } or print("caught");
'
在eval
中添加额外的范围可以解决问题。
$x = 123; eval { { local $x = 456; } 1 } or print("caught");