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

Posted

技术标签:

【中文标题】Perl 5.14 神秘的拼写错误错误消息、DESTROY 和 AUTOLOAD【英文标题】:Perl 5.14 Mysterious Misspelled Error Message, DESTROY, and AUTOLOAD 【发布时间】:2013-01-02 08:38:28 【问题描述】:

我有一个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

让我印象深刻的第一件事是 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 的调用。

最好的处理方法是什么?

【问题讨论】:

【参考方案1】:

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

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

【讨论】:

我在Advanced Perl Programming 中找到了指向return if $AUTOLOAD =~ /::DESTROY$/ 解决方案的链接。这就是我在我的代码中所做的。我可能会重写钩子并消除AUTOLOAD 这比它的价值更痛苦。【参考方案2】:

它确实发生在 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

【讨论】:

以上是关于Perl 5.14 神秘的拼写错误错误消息、DESTROY 和 AUTOLOAD的主要内容,如果未能解决你的问题,请参考以下文章

从 Perl 5.14 升级到 5.28 后,我的 Perl 找不到 local::lib

Perl:如何在没有错误消息的情况下“死”?

在 Perl 的 ssh 连接中捕获错误主机名的错误消息(使用 Net::OpenSSH)

如何处理错误消息Please install the gcc make perl packages

神秘的链接器错误

无效的命令“订单”,可能拼写错误或由未包含在服务器配置中的模块定义失败