loris has asked for the wisdom of the Perl Monks concerning the following question:

To those wiser than I:

Knowing a little about Perl and a little about OO I had a look at perltoot and copied the two snippets of code in the section Autoloaded Data Methods into a module and then tried it out with a script which just created a new Person().
To my surprise running the script produced the message:
(in cleanup) Can't access `DESTROY' field in class Person at ./test.pl + line 0
If I add DESTROY to %fields, the message disappears, but this strikes me as an odd thing to have to do.

Could anyone enlighten me, please?

Replies are listed 'Best First'.
Re: perltoot: Problem with Autoloaded Data Methods
by fireartist (Chaplain) on Oct 08, 2004 at 12:15 UTC
    I've been hit by this before.
    If you have an AUTOLOAD method and a DESTROY method isn't defined, your AUTOLOAD will catch it. Just add this to the module.
    sub DESTROY {}
    update
    To be more explicit: When the object is destroyed (goes out of scope / program ends) the module's DESTROY method will automatically be called. Because you have AUTOLOAD defined, it will catch that call.
Re: perltoot: Problem with Autoloaded Data Methods
by bpphillips (Friar) on Oct 08, 2004 at 12:19 UTC
    When your object goes out of scope, perl looks for a sub DESTROY in your module. Since you haven't defined one, the AUTOLOAD method takes over. Your AUTOLOAD method then checks to see if your object has a field by the same name of the method call and die's if it doesn't.

    You can do a couple different things. First, you could add a DESTROY stub so that the AUTOLOADER doesn't come into play:
    sub DESTROY {}
    or you can change your sub AUTOLOAD so that it ignores this method call that perl does automatically:
    my $name = $AUTOLOAD; $name =~ s/.*://; # strip fully-qualified portion # this is new... return 0 if($name eq 'DESTROY'); unless (exists $self->{_permitted}->{$name} ) { croak "Can't access `$name' field in class $type"; }
    That should take care of the error.
    Update Looks like I was a bit late in my reply as someone else already suggested the sub DESTROY {} solution... Oh well