I believe that I've stumbled across a problem with perl's garbage collector. I'm working with a set of nested objects/datastructures which (broken down to the ugly parts) can be described like this:
Let's start with a hash which contains all global configuration data, particularly the required database handler. This hash (let's call it %glob) is needed to bless a user-object and is furthermore a property of $user. It's all part of a website so CGI::Session becomes handy to control the user-session. As the user is needed in other parts of the programm the object is stored into %glob;
my $dbh = $glob{dbh}; my $session = new CGI::Session("driver:MySQL;id:MD5", $sid, { Handle = +> $dbh, LockHandler => $dbh }); my $user = bless ( { glob => \%glob, session => $session }, $class ); $glob{user} = $user;
Now I need an HTML Page.
my $page = bless ( { glob => \%glob }, $class );
So far, everything seems to work fine. The problem occurs when the script terminates. CGI::Session builds its data up on creation, manipulates it if required and writes the session into the database not until the DESTROY method of the session-object gets called. Unfortunately at this point the database handler is already destroyed and an error is yielded.
I've tried to narrow it down by writing DESTROY methods for both the page- and the user-object. The page gets destroyed first and with the page goes the database handler. A possible solution may be to destroy the user-object within the page's DESTROY method but then I'll had to consider that some pages may have subpages and remove the user-object from %glob before blessing a new page-object. (Actually I've already tried this - with the result that CGI::Session yields a slightly different error.)
From my point of view my problem seems to be that I disagree with perl's garbage collector on when to destroy my objects. Is there any way to tell him that I'd like to destroy the user-object first (including the session-object) and then the page-object?
[note]Oh dear fellow monks, I can't even express my gratitude to this great site. By writing my problem down, trying to find the proper words to describe my problem, reflecting the different search-paths I've already tried and repeatedly thinking about the possible solutions, I've found a solution to my problem.
After the main function I'm calling the DESTROY method of the user-object which calls the appropriate method of the session-object to flush and destroy the session. As the page-object doesn't need any special treatment when it gets destroyed after the main script terminates, I don't care if the database handler is available then.
However, this leads me to another problem: should I delete my question or post it as part of contribution for other monks confronted with a similar problem as mine? I've chosen the latter but still remain to ask if there are other (better) solutions.
In reply to destroying object by slayven
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |