The documentation in perlobj, as quoted by aitap, says:

When the last reference to an object goes away, the object is destroyed. If you only have one reference to an object stored in a lexical scalar, the object is destroyed when that scalar goes out of scope.

This can be read in two ways:

  1. The object’s DESTROY method (if any) is called immediately when its reference count drops to zero.
  2. When an object’s reference count drops to zero, it is scheduled for destruction, and the DESTROY method (if any) is called by the Perl runtime at the first opportunity.

The consensus in this thread seems to be that interpretation (1) is correct, but ggoebel has in fact provided a counterexample — notwithstanding the fact that ggoebel himself says:

Note that the object is destroyed before the print statement in the destructor is flushed to STDOUT

But I don’t believe that flushing the output filehandle plays any part here. Adding $| = 1; at the top of the code makes no difference to the output. My understanding is that in ggoebel’s example what happens is this:

That is, the error warning message indicates only that $obj is undef, not that the object to which $obj formerly pointed has been destroyed.

As evidence I offer the following adaptation of ggoebel ’s example, enhanced to give the object a resource which it modifies in its DESTROY method:

#! perl use strict; use warnings; $| = 1; #--------------------------------------------------------------------- +--------- package Phaser; sub new { my ($class, $name) = @_; my $self = {}; $self->{name} = $name; return bless $self, $class; } #--------------------------------------------------------------------- +--------- package Dalek; sub new { my ($class, $phaser_ref) = @_; my $self = {}; $self->{phaser} = $phaser_ref; return bless $self, $class; } sub exterminate { return 'Firing phaser ' . $_[0]->{phaser}->{name} . "\n"; } sub obey { return 'obey'; } sub DESTROY { my ($self) = @_; print 'DESTROYing a Dalek (phaser is ', $self->{phaser}->{name}, " +)\n"; $self->{phaser}->{name} = 'Obliterator'; } #--------------------------------------------------------------------- +--------- package main; my $phaser = Phaser->new('Exterminator'); my $enemy = Dalek ->new($phaser); print 'My enemy is a ', ref $enemy, ' with a phaser named ', $phaser->{name}, "\n"; print $enemy->exterminate(); print 'My enemy must ', $enemy->obey(), undef($enemy), '. His phaser is named ', $phaser->{name}, eval('$enemy->exterminate()'), ". Bye!\n"; print $@ if $@; print 'The phaser is named ', $phaser->{name}, "\n";

Output:

16:59 >perl 552_SoPW.pl My enemy is a Dalek with a phaser named Exterminator Firing phaser Exterminator Use of uninitialized value in print at 552_SoPW.pl line 67. My enemy must obey. His phaser is named Exterminator. Bye! DESTROYing a Dalek (phaser is Exterminator) Can't call method "exterminate" on an undefined value at (eval 1) line + 1. The phaser is named Obliterator 16:59 >

As can be seen by the change of phaser name from “Exterminator” to “Obliterator”, the DESTROY method is not called until immediately after the print statement completes.

I conclude that the documentation should be read according to the second interpretation. If this were C++, we could refer to an account of “sequence points” for a precise statement of when the DESTROY method is called. As it is, the following seems like a good rule of thumb for destructors in Perl:

When an object’s reference count falls to zero, its DESTROY method will be called immediately upon completion of the statement (not expression) in which the reference count is decremented.

In some (probably rare) cases, this might be an important distinction to keep in mind.

Hope that helps,

Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,


In reply to Re: when is destroy function called by Athanasius
in thread when is destroy function called by david2008

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.