in reply to Re: order of destructor calls upon call of exit()
in thread order of destructor calls upon call of exit()

A Perl variable (such as a scalar, an array, but most-importantly an object) is destroyed when its reference count goes to zero. Reference counts usually go to zero when you leave the scope in which the object was declared (unless references to it still exist elsewhere) or right after the last object to have a reference to it is destroyed.

This is very handy since if $a needs $b, then $a holds a reference to $b. This will mean that $a is destroyed before $b so that $a's DESTROY method can use $b rather safely. The "rather" is because there are some cases where this destruction order guarantee will not be honored.

The biggest exception is global variables. The reference count on a global variable (A.K.A. a package variable or an "our" variable) never goes to zero. All globals are destroyed when the Perl interpretter is torn down in a phase called, dramatically enough, "global destruction". During this phase, all variables are destroyed without regard to reference counts and in an order that is probably best thought of as simply "undefined". The order is actually defined, but it has changed and probably will change again and isn't a particularly useful order from the script writer's perspective, so you'll have to go look it (well, them) up if you are really curious (that may be what merlyn was referring to when he talks about memory allocation order).

I was worried that an unexpected call to die would also simply trigger global destruction, resulting in "random" destruction order again (that would be bad). However, testing shows that die does an orderly unwinding of the nested scopes, decrementing reference counts and destroying things in the desired order.

Uncaught signals that kill your process will prevent the destruction of any and all Perl variables. The operating system will simply free the memory allocated to the process -- no Perl code will be given a chance to "clean up". So you'll want to catch likely signals and try as safely as possible to tell your program to shut itself down in an orderly manner. With proper use of destructors, a simple

$SIG{HUP}= sub { die "Caught HUP\n" };
is all it takes. It isn't completely safe but only because Perl signal handlers aren't completely safe no matter what they do.

So I would recommend not doing destruction in signal handlers (die in the signal handler and let Perl do the destruction). I would also recommend not using END since such code usually needs to happen after you are sure you are done with some things but before you have destroyed other things. If you do clean up in destructors, then it usually just falls out that the clean up is done in the correct order and is done whether the program exiting normally or failed (if the operating system gives you that chance).

Oh, and circular references will prevent members of the circle and things that they refer to from being destroyed until the global destruction phase. Note that even if Perl detected and destroyed circular references, the order of destruction would not be easy to predict since there is no "top" in a circular reference.

        - tye (but my friends call me "Tye")