12.6. Instance DestructorsAs with any other referent in Perl, when the last reference to an object goes away, its memory is implicitly recycled. With an object, you have the opportunity to capture control just as this is about to happen by defining a DESTROY subroutine in the class's package. This method is triggered automatically at the appropriate moment, with the about-to-be-recycled object as its only argument. Destructors are rarely needed in Perl, because memory management is handled automatically for you. Some objects, though, may have state outside the memory system that you'd like to attend to, such as filehandles or database connections. package MailNotify; sub DESTROY { my $self = shift; my $fh = $self->{mailhandle}; my $id = $self->{name}; print $fh "\n$id is signing off at " . localtime() . "\n"; close $fh; # close pipe to mailer } Just as Perl uses only a single method to construct an object even when the constructor's class inherits from one or more other classes, Perl also uses only one DESTROY method per object destroyed regardless of inheritance. In other words, Perl does not do hierarchical destruction for you. If your class overrides a superclass's destructor, then your DESTROY method may need to invoke the DESTROY method for any applicable base classes: This applies only to inherited classes; an object that is simply contained within the current object--as, for example, one value in a larger hash--will be freed and destroyed automatically. This is one reason why containership via mere aggregation (sometimes called a "has-a" relationship) is often cleaner and clearer than inheritance (an "is-a" relationship). In other words, often you really only need to store one object inside another directly instead of through inheritance, which can add unnecessary complexity. Sometimes when users reach for multiple inheritance, single inheritance will suffice.sub DESTROY { my $self = shift; # check for an overridden destructor... $self->SUPER::DESTROY if $self->can("SUPER::DESTROY"); # now do your own thing before or after } Explicitly calling DESTROY is possible but seldom needed. It might even be harmful since running the destructor more than once on the same object could prove unpleasant. 12.6.1. Garbage Collection with DESTROY MethodsAs described in the section Section 12.5.2, "Garbage Collection, Circular References, and Weak References" in Chapter 8, "References", a variable that refers to itself (or multiple variables that refer to one another indirectly) will not be freed until the program (or embedded interpreter) is about to exit. If you want to reclaim the memory any earlier, you usually have to explicitly break the reference or weaken it using the WeakRef module on CPAN. With objects, an alternative solution is to create a container class that holds a pointer to the self-referential data structure. Define a DESTROY method for the containing object's class that manually breaks the circularities in the self-referential structure. You can find an example of this in Chapter 13 of the Perl Cookbook in the recipe 13.13, "Coping with Circular Data Structures". When an interpreter shuts down, all its objects are destroyed, which is important for multithreaded or embedded Perl applications. Objects are always destroyed in a separate pass before ordinary references. This is to prevent DESTROY methods from using references that have themselves been destroyed. (And also because plain references are only garbage-collected in embedded interpreters, since exiting a process is a very fast way of reclaiming references. But exiting won't run the object destructors, so Perl does that first.) Copyright © 2002 O'Reilly & Associates. All rights reserved. |
|