【问题标题】:Perl 5.14 Mysterious Misspelled Error Message, DESTROY, and AUTOLOADPerl 5.14 神秘的拼写错误错误消息、DESTROY 和 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 的调用。

最好的处理方法是什么?

【问题讨论】:

    标签: perl 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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-11-09
      • 1970-01-01
      • 2015-09-04
      • 1970-01-01
      • 2021-01-18
      • 2013-03-29
      • 1970-01-01
      • 2015-03-13
      相关资源
      最近更新 更多