Unexpected behavior

phillup on 2004-11-11T21:16:26

I'm experiencing behavior that was not expected, and I'm wondering if this is "normal".

I have a "session" object that has a "has a" relationship with CGI::Session.

If I make sure to undef my object before the program ends, then everything is fine.

However, if I don't specifically undef my session object... and instead rely on the default garbage collection... it looks like the CGI::Session object I'm using gets destroyed BEFORE my session object gets destroyed.

It would seem to me that there should still be a reference count to the CGI::Session object as long as my object exists and that my session object would be destroyed first. Isn't this the way it is supposed to happen?

I managed to squeak out a diagnostic message that said

DESTROY created new reference to dead object



and have litterd my code with diagnostic print statements. Everything is fine until I make a call to the CGI::Session's param method and then the program spits out:

Can't call method "param" on an undefined value...


I am about to write a "minimal" object to try and replicate (and hopefully fix) the problem. But, I was wondering if I'm just totally mixed up on Perl's garbage collection.

TIA

---

UPDATE: By adding a print statement to my destructor and the destructor in CGI::Session I can definitely say that CGI::Session is being destroyed before my object is.

---

UPDATE 2: I've posted code that demonstrates the problem in a new journal entry.


Is it at interpreter shut down?

autarch on 2004-11-11T23:09:00

I've seen similar weirdness when DESTROY is being called during the interpreter shut down. It seems like sometimes contained objects get destroyed before their containers.

During other object destruction (when an object goes out of scope but the program keeps going), the order of destruction seems to be correct.

Re:Is it at interpreter shut down?

phillup on 2004-11-12T00:29:26

Yes, it is when the program ends.

Interestingly, if I have something like this then everything is OK.
#! /usr/bin/perl
 
use strict;
use warnings;
 
use My::Session;
my $session = new My::Session;
 
print $session->valid() ? "Session is valid\n" : "Session is NOT valid\n";
But, if I do something like this then I see the error message.
#! /usr/bin/perl
 
use strict;
use warnings;
 
use My::Session;
my $session = new My::Session;
 
sub skipme{
  my $id = $session->id();
  print "ID: $id\n";
}
 
print $session->valid() ? "Session is valid\n" : "Session is NOT valid\n";
Notice that the variable $session is referenced in the sub, but the sub isn't called. I think it might be closure related but I don't know enough about closures to be sure...

The second one is very close to my test case. I'm currently paring down the My::Session (not it's real name ;-)) module to simplify things as much as possible.

It certainly seems like Perl should just "Do the right thing" in this case.