David W.
David W.

Reputation: 107080

Perl 5.14 Mysterious Misspelled Error Message, DESTROY, and AUTOLOAD

I have a Perl Subversion pre-commit hook. A mysterious error message popped up with someone using Perl 5.14 that had not been seen in earlier versions of Perl:

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

First thing that struck me was the misspelling of nonexistent. Boy, that guy can't spell at all! It's almost as bad as... my spelling... wait a second...

In line 1251 of my code is this from my AUTOLOAD subroutine:

croak qq(Non existant subroutine called $AUTOLOAD);

Yup, that's the error line.

This didn't happen in Perl 5.12 which is what I use on my Mac and is on my PC in both Strawberry and ActiveState flavors. It also does't happen our corporate Linux boxes which range from Perl 5.8 to 5.10.

It looks like Perl is calling DESTROY, and that's being picked up by my AUTOLOAD subroutine, and since DESTROY is a non existant subroutine in my package, the AUTOLOAD subroutine displays this error message.

What is the best way of handling this?

Upvotes: 2

Views: 202

Answers (2)

hobbs
hobbs

Reputation: 240314

This should have always happened. If it didn't happen for you in the past, there might have been a bug in perl that interacted with your code to cause DESTROY not to get called. But in 5.14, it's working as designed. It's common for AUTOLOAD subs to do something like return if $AUTOLOAD =~ /::DESTROY$/ to avoid any problems with destruction.

Having an explicit sub DESTROY { } is faster than dispatching through AUTOLOAD, but it's the wrong thing to do if you have any superclasses and any of your superclasses have DESTROY methods (they won't get run). Therefore I consider it a bad habit to get into, even for classes that don't inherit anything.

Upvotes: 3

ikegami
ikegami

Reputation: 386386

It did happen in 5.12. 5.10.1 is the oldest I have, and it happened there too.

>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

Upvotes: 0

Related Questions