in reply to Re: Objects and undefined values
in thread Objects and undefined values

Thanks chromatic, for the quick reply!

Yes, the DESTROY is this:

sub DESTROY { my ($self, @args) = @_; $self->print("End Logging"); undef $self->{'_fh'}; return 1; }
And commenting out the $self->print line kills the error.

Now to understand why... Shouldn't $self->print be the same as calling it as $log->print? The filehandle is still defined until the next line...Hmmm. This is why perl objects confuse me! ;-)

Since DESTROY is being called implicitly, is the problem that it isn't getting all of the $log object, or perhaps there is a bug in the way the DESTROY object is handling the elements? Should I break out the elements as found in the 'new' method, like so:

sub new{ my ($class, @arg) = @_; my %arg = @arg; ... }
Where we're breaking the array args into a hash arg. Nope, guess not, as it doesn't fix the error.

Replies are listed 'Best First'.
Re: Re: Re: Objects and undefined values
by chromatic (Archbishop) on Feb 07, 2002 at 22:39 UTC
    You also mention that $log is a global object. By the end of the program, are all references to it explicitly destroyed, or are you relying on Perl to clean it up for you as the main package goes out of scope?

    If it's the latter (and you're usually okay doing that, except for when you aren't), you're probably getting tripped up by Perl's unreliable destruction order. Instead of What We All Expect, where objects and variables are cleaned up in reverse order of their creation, there's a mad rush for the exit, and occasionally things get trampled underfoot. Unfortunately, that appears to mean the FileHandle is gone before $log is.

    You have two solutions -- move your final log message out of DESTROY, or explicitly undefined the last reference to the $log object before falling off the end of the program.

      chromatic, you are my hero!

      I thought I was cleaning up all references. But your post made me look again, and I realized that the problem was that I'm using interrupts to end the program when it runs as a daemon, and I wasn't cleaning up $log in the interrupt function which performs an 'exit'. And this tells me why I wasn't getting the error when I first started using the class, because I was working with the build mode, which doesn't fork and needs no signal to be stopped.

      Thanks so much for your guidance. Happily, I can now move onto the problem that lead me to add extensive logging to my program in the first place!

Re: Re: Re: Objects and undefined values
by SwellJoe (Scribe) on Feb 07, 2002 at 22:22 UTC
    Ok, replying to myself because I think I'm tracking down my problem or at least catching a glimpse of it.

    I am daemonizing my program in the normal case, so I fork && exit near the top in the primary subroutine that is called if we are to run in daemon mode--but this fork comes after the log object construction. So I'm creating two of the log object, I think...

    So I tried breaking out the check for starting in daemon mode, put the log object construction right after the check and before the actual daemonizing subroutine call. So I should have a global $log object throughout either daemon mode, or the non-daemon mode. But alas I still get the error when signalling the program to shutdown (but not immediately on run as I was before, thus the reason I think I'm catching a fleeting glimpse of what is going wrong).

    I've commented out the 'undef $log' at the end of the program as a test, but no result...and $log is not going out of scope until the end of the program because it is a global object. So does this mean the DESTROY method is called /after/ all objects are already out of scope? That just doesn't seem correct.

    So what am I missing? (I know I'm missing something, because it can't be that DESTROY is called after the object is already gone. Or am I just thinking too hard?)