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

In reply to RE: Re: order of destructor calls upon call of exit() by tye
in thread order of destructor calls upon call of exit() by princepawn

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.