Perl eval奇怪的案例

时间:2014-02-04 21:14:50

标签: perl

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

1 个答案:

答案 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");