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")
|