Here is a minimal script that demonstrates (on my system) the strange behavior I am experiencing.
If I uncomment the undef statement, then everything seems to work. But, if I let Perl take out the garbage it looks like my CGI::Session object gets destroyed before my own session object is destroyed. Even tho I still have a reference to the object. (Actually, my reference goes away!)
I can work around the problem by making sure I trigger the object destruction myself. But, I'd really like to know if the problem is in my mental picture of how things are supposed to work.
UPDATE: It appears to be my mental picture.
Apparently global garbage destruction is somewhat random in order. So, make sure you take out your own garbage if the order is important!
Any comments greatly appreciated!
-------
#!
/usr/bin/perl
use strict;
use warnings;
my $session = new My::Session;
sub skipme{
my $test = $session->{test}; # no I don't normally access the object data directly
# I just need to use the object in the sub to trigger
# the problem and I want to reduce the number of methods
# to the bare minimum to demonstrate the problem
} # sub skipme
print "\nDone\n";
#undef $session;
{#-----------------------------------------------------------------
package My::Session;
use strict;
use warnings;
my $session_dir = '/tmp/cgisession/';
use CGI::Session::File;
sub new{
# get our class of object
my $CLASS = shift;
my $SELF = {};
# get a new storage session
$SELF->{session} = new CGI::Session("driver:File;serializer:FreezeThaw", undef, {Directory => $session_dir})
|| die 'Could not get new session store!';
# and bless ourself
bless $SELF, $CLASS;
return $SELF;
} # sub new
sub DESTROY {
my $SELF = shift;
print "Hey!! Someone stole my session!\n" unless $SELF->{session};
} # sub DESTROY
}#-----------------------------------------------------------------
Closures. (Score:2)
You've got a closure there referencing $session inside
skipme(). If you pass the object in instead, things will probably work as you expect.-Dom
Re:Closures. (Score:1)
Or does the closure some how mess up the reference count?
It seems to me that the $session instance has a reference to a CGI::Session object, so the CGI::Session object should not be destroyed until after the $session variable is.
Or, do I have that wrong?
It dies during global destruction... (Score:1)
The only safe way to handle things here is make sure that your objects die before global destruction.
Re:It dies during global destruction... (Score:2)
Re:It dies during global destruction... (Score:1)
And global destruction's unordered, which is likely where your problem lies.
Do you have a reference for this? I've looked and can't find a thing about it.
I did find this in Programming Perl, 3rd Edition (page 331)
Re:It dies during global destruction... (Score:1)
Re:It dies during global destruction... (Score:2)