2

我有一个Perl Subversion 预提交钩子。使用 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

首先让我印象深刻的是nonexistent的拼写错误。小子,那家伙根本不会拼音!这几乎和……我的拼写一样糟糕……等一下……

在我的代码的第 1251 行,这是来自我的AUTOLOAD子程序:

croak qq(Non existant subroutine called $AUTOLOAD);

是的,这就是错误行。

这在 Perl 5.12 中没有发生,这是我在 Mac 上使用的,并且在我的 PC 上具有草莓和 ActiveState 两种风格。从 Perl 5.8 到 5.10 的企业 Linux 机器也不会发生这种情况。

看起来 Perl 正在调用DESTROY,并且它正在被我的子例程拾取AUTOLOAD,并且由于在我的包中DESTROY不存在AUTOLOAD的子例程,因此子例程会显示此错误消息。

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

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

4

2 回答 2

3

这应该一直发生。如果您过去没有发生这种情况,那么 perl 中可能存在与您的代码交互的错误,导致 DESTROY 不被调用。但在 5.14 中,它按设计工作。AUTOLOAD 潜艇通常会做一些事情return if $AUTOLOAD =~ /::DESTROY$/来避免任何破坏问题。

拥有显式sub DESTROY { }比通过 调度更快AUTOLOAD,但如果您有任何超类并且您的任何超类都有DESTROY方法(它们不会运行),那么这是错误的做法。因此,我认为这是一个坏习惯,即使对于不继承任何东西的类也是如此。

于 2013-01-18T20:04:48.837 回答
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
于 2013-01-18T19:05:07.303 回答