对于Perl 5.8与5.10和5.12的子程序中的代码延迟评估有什么区别?

Bro*_*ock 8 perl perl5.8

在Perl 5.8下,这段代码的行为与在Perl 5.12下的行为不同:

my $badcode = sub { 1 / 0 };
print "Made it past the bad code.\n";
Run Code Online (Sandbox Code Playgroud)

当我在5.8下运行它时,即使我从未执行分区,我也会收到错误:

[brock@chase tmp]$ /usr/bin/perl -v  

This is perl, v5.8.8 built for i486-linux-gnu-thread-multi

[brock@chase tmp]$ /usr/bin/perl badcode.pl  
Illegal division by zero at badcode.pl line 1.

[brock@chase tmp]$ /usr/local/bin/perl -v  

This is perl 5, version 12, subversion 0 (v5.12.0) built for i686-linux  

[brock@chase tmp]$ /usr/local/bin/perl badcode.pl  
Made it past the bad code.

在perl 5.10.1下,它的行为与在5.12下的行为相同:

brock@laptop:/var/tmp$ perl -v

This is perl, v5.10.1 (*) built for i486-linux-gnu-thread-multi

brock@laptop:/var/tmp$ perl badcode.pl  
Made it past the bad code.

我使用命名子例程获得相同的结果,例如

sub badcode { 1 / 0 }
Run Code Online (Sandbox Code Playgroud)

我在perl5100delta pod中没有看到任何相关内容.这是一个无证的变化吗?其他一些变化的意外副作用?(为了记录,我认为5.10和5.12正在做正确的事.)

Eva*_*oll 17

我相信这是有计划的,我确实在perl5100delta.pod中看到了这一点:

不断折叠的例外情况

常量折叠例程现在包装在异常处理程序中,如果fold抛出异常(例如尝试评估0/0),perl现在保留当前的optree,而不是中止整个程序.如果没有这种更改,程序将无法编译,如果它们具有恰好生成异常的表达式,即使这些表达式是在运行时永远无法访问的代码中.(尼古拉斯·克拉克,戴夫·米切尔)

它只是与除零异常有关,不会导致编译阶段中止.

  • @Brock =>那是因为表达式中的变量阻止常量文件夹在编译期间减少它.如果你只是需要抛出异常,为什么不``我的$ badsub = sub {die"badsub死了\n"};` (2认同)