Perl 5.14神秘拼写错误消息,DESTROY和AUTOLOAD

时间:2013-01-18 15:35:40

标签: perl autoload destroy

我有Perl Subversion pre-commit hook。使用Perl 5.14的人弹出了一个神秘的错误消息,这个消息在早期版本的Perl中没有出现过:

(in cleanup) Non existant subroutine called Section::File::DESTROY at /home/tftung/svn_repos/hooks/pre-commit-kitchen-sink-hook.pl line 282

让我印象深刻的是不存在的拼写错误。男孩,那家伙根本不能拼!它差不多......我的拼写......等一下......

我的代码的第1251行来自我的AUTOLOAD子例程:

croak qq(Non existant subroutine called $AUTOLOAD);

是的,这是错误行。

在Perl 5.12中没有发生这种情况,这是我在Mac上使用的,并且在我的PC上都有草莓和ActiveState两种口味。我们的企业Linux机箱也不会发生,其范围从Perl 5.8到5.10。

看起来Perl正在调用DESTROY,并且我的AUTOLOAD子例程正在调用它,并且DESTROY是我的不存在的子例程包,AUTOLOAD子例程显示此错误消息。

  • 这是新版Perl中的错误还是功能?看来AUTOLOAD接听DESTROY的电话是相当新的功能
  • 我该如何解决这个问题?我的意思是除了摆脱我的AUTOLOAD子程序,这可能是正确的答案。我计划从头开始完全重写这个脚本,所以我宁愿不做很多工作。
    • 我可以写一个什么都不做的DESTROY子程序。
    • 我可以让我的AUTOLOAD例程忽略对DESTROY的调用。

处理此问题的最佳方法是什么?

2 个答案:

答案 0 :(得分:3)

这应该总是发生。如果过去没有发生这种情况,那么perl中可能存在与您的代码交互以导致DESTROY无法被调用的错误。但是在5.14中,它按设计工作。 AUTOLOAD subs通常会执行类似return if $AUTOLOAD =~ /::DESTROY$/的操作,以避免任何破坏问题。

明确sub DESTROY { }比通过AUTOLOAD调度更快,但如果您有任何超类并且您的任何超类都有DESTROY方法(他们赢了',那么这是错误的做法跑步)。因此,即使对于没有继承任何内容的课程,我也认为这是一个坏习惯。

答案 1 :(得分:0)

确实发生在5.12。 5.10.1是我拥有的最古老的,它也发生在那里。

>perl5101-ap1007\bin\perl -wE"sub AUTOLOAD { say $AUTOLOAD; } our $x=bless({});"
main::DESTROY

>perl5121-ap1201\bin\perl -wE"sub AUTOLOAD { say $AUTOLOAD; } our $x=bless({});"
main::DESTROY

>perl5123-ap1204\bin\perl -wE"sub AUTOLOAD { say $AUTOLOAD; } our $x=bless({});"
main::DESTROY

>perl5124-ap1205\bin\perl -wE"sub AUTOLOAD { say $AUTOLOAD; } our $x=bless({});"
main::DESTROY

>perl5140-ap1400\bin\perl -wE"sub AUTOLOAD { say $AUTOLOAD; } our $x=bless({});"
main::DESTROY

>perl5142-ap1402\bin\perl -wE"sub AUTOLOAD { say $AUTOLOAD; } our $x=bless({});"
main::DESTROY

>perl5161-ap1601\bin\perl -wE"sub AUTOLOAD { say $AUTOLOAD; } our $x=bless({});"
main::DESTROY