Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot

AutoLoader destroy issue

by Anonymous Monk
on Aug 07, 2012 at 21:01 UTC ( #986086=perlquestion: print w/replies, xml ) Need Help??
Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hi monks, I have a MyOwnTable class which inherits from Data::Table and several derived classes (for example, A) which inherit from MyOwnTable. When I create an instance of A, perform some operations on A (which are not necessary, btw), and then exit the script, I get the following warnings
Use of uninitialized value in require at //ms/dist/perl5/PROJ/AutoLoad +er/5.68/lib/perl5/ line 27 during global destruction. Use of uninitialized value in require at //ms/dist/perl5/PROJ/AutoLoad +er/5.68/lib/perl5/ line 27 during global destruction. Use of uninitialized value in require at //ms/dist/perl5/PROJ/AutoLoad +er/5.68/lib/perl5/ line 27 during global destruction. Use of uninitialized value in require at //ms/dist/perl5/PROJ/AutoLoad +er/5.68/lib/perl5/ line 27 during global destruction.
When I look at line 27 in, I find the following
AUTOLOAD { my $sub = $AUTOLOAD; my $filename = AutoLoader::find_filename( $sub ); my $save = $@; local $!; # Do not munge the value. eval { local $SIG{__DIE__}; require $filename }; ## line 27!!!! if ($@) { if (substr($sub,-9) eq '::DESTROY') { no strict 'refs'; *$sub = sub {}; $@ = undef; } elsif ($@ =~ /^Can't locate/) { # The load might just have failed because the filename was + too # long for some old SVR3 systems which treat long names as + errors. # If we can successfully truncate a long name then it's wo +rth a go. # There is a slight risk that we could pick up the wrong f +ile here # but autosplit should have warned about that when splitti +ng. if ($filename =~ s/(\w{12,})\.al$/substr($1,0,11).".al"/e) +{ eval { local $SIG{__DIE__}; require $filename }; } } if ($@){ $@ =~ s/ at .*\n//; my $error = $@; require Carp; Carp::croak($error); } } $@ = $save; goto &$sub; }
when I put a breakpoint in AutoLoader::AUTOLOAD, the missing function seems to be A::DESTROY. So, I tried putting a DESTROY method in A (not sure what code should go in there). This resulted in AutoLoader::AUTOLOAD not getting called, but the error/warning still showing up (this is puzzling). Can anyone help me ? thanks, Michael

Replies are listed 'Best First'.
Re: AutoLoader destroy issue
by Khen1950fx (Canon) on Aug 07, 2012 at 22:00 UTC
    Put an empty DESTROY subroutine after AUTOLOAD and the problem goes away.
    #!perl -w package CD::Music; use strict; use vars '$AUTOLOAD'; sub AUTOLOAD { my ($self) = @_; $AUTOLOAD =~ /.*::get(_\w+)/ or die "No such method: $AUTOLOAD"; exists $self->{$1} or die "No such attribute: $1"; return $self->{$1} } sub DESTROY { } { my $_count = 0; sub get_count { $_count } my $_incr_count = sub { ++$_count }; sub new { my ($class) = @_; $_incr_count->(); bless { _name => $_[1], _artist => $_[2], _publisher => $_[3], _ISBN => $_[4], _tracks => $_[5], _room => $_[6], _shelf => $_[7], _rating => $_[8], }, $class; } sub get_location { ($_[0]->{_room}, $_[0]->{_shelf}) } sub set_location { my ($self, $shelf, $room) = @_; $self->{_room} = $room if $room; $self->{_shelf} = $shelf if $shelf; return ($self->{_room}, $self->{_shelf}); } sub set_rating { my ($self, $rating) = @_; $self->{_rating} = $rating if defined $rating; return $self->{_rating}; } } package main; my $cd = CD::Music->new( "Canon in D", "Pachelbel", "Boering Mu\u00df +GmbH", "1729-67836847-1", 1, 8, 8, 5.0); print $cd->get_name, ", ", $cd->get_publisher, "\n"; printf "Room %s, shelf %s\n", $cd->get_location; $cd->set_location(5,3); print CD::Music->get_count, "\n";
      Hi Khen1950fx, thanks for your response. My AUTOLOAD is in and not in my own code. Do I need to define it in MyOwnTable or A or both ? I tried defining it in both A and MyOwnTable (like you did in CD::Music) along with the empty DESTROY subroutine, but I'm still receiving the error/warning. :( thanks, Michael
Re: AutoLoader destroy issue (inheritance--)
by tye (Sage) on Aug 07, 2012 at 23:05 UTC

    Stop over-using inheritance from classes that over-use inheritance so that you end up inheriting from AutoLoader for no good reason. (Did you also know that your MyOwnTable "isa" Exporter and your A "isa" Exporter? Did you want them to be?)

    File a bug against the Data::Table module asking that the author remove the "require AutoLoader;" line from his module since AutoLoader's documentation notes:

    To use AutoLoader, the author of a module has to place the definitions of subroutines to be autoloaded after an __END__ token.

    and the source code for Data/ has no sub definitions after the __END__ token.

    Perhaps ask that author where the "require AutoLoader;" line came from so perhaps some documentation or "help me write a module" tool could be updated to not encourage such inanity.

    - tye        

      Pointed the author to this thread, 1.68 is now on its way to CPAN. Will follow up to see if the author remembers why that was in there (boilerplate?).

      Update: Author thinks it was a cut-n-paste from another module. Doesn't remember exactly where it was originally from.


      Thank you for your response, tye, I appreciate your help. Contacting the author might be a challenging option that would most likely not yield timely results. Any other workarounds/hacks/suggestions ? Regards, Michael

        Any other workarounds/hacks/suggestions ?

        Locate Date/ and remove that line from your copy

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://986086]
Approved by chacham
[hippo]: Are you any good at perl?

How do I use this? | Other CB clients
Other Users?
Others chanting in the Monastery: (6)
As of 2018-06-23 09:10 GMT
Find Nodes?
    Voting Booth?
    Should cpanminus be part of the standard Perl release?

    Results (125 votes). Check out past polls.