ЭЛЕКТРОННАЯ БИБЛИОТЕКА КОАПП
Сборники Художественной, Технической, Справочной, Английской, Нормативной, Исторической, и др. литературы.



13.2. Destroying an Object

Problem

You want to run special code whenever an object is no longer used. This is sometimes needed when the object is an interface to the outside world  - or contains circular data structures  - and must clean up after itself. You might remove temporary files, break circular links, gracefully disconnect from a socket, or kill a spawned subprocess.

Solution

Create a method named DESTROY. This will be called when there are no more references to the object, or else when the program shuts down, whichever comes first. You don't need to do any memory deallocation here, just any finalization code if it makes sense for the class.

sub DESTROY {
    my $self = shift;
    printf("$self dying at %s\n", scalar localtime);
} 

Discussion

Every story has a beginning and an end. The beginning of the object's story is its constructor, explicitly called when the object comes into existence. The end of its story is the destructor, a method implicitly called when an object leaves this life. Any per-object clean-up code is placed in the destructor, which must be named DESTROY.

Why can't destructors have arbitrary names? Because, although a constructor is explicitly called by name, a destructor is not. Destruction happens automatically via Perl's garbage collection (GC) system, which is currently implemented as a quick but lazy reference-based GC system. To know what to call, Perl insists that the destructor be named DESTROY. If more than one object goes out of scope at once, Perl doesn't promise to call the destructors in a particular order.

Why is DESTROY in all caps? Perl on occasion uses purely uppercase function names as a convention to indicate that the function will be automatically called by Perl. Others that are called implicitly include BEGIN, END, AUTOLOAD, plus all methods used by tied objects (see Recipe 13.15), like STORE and FETCH.

The user doesn't care when the destructor is called. It just happens when it's supposed to. In languages without any form of GC, this is undependable, so the programmer must explicitly call the destructor to clean up memory and state, crossing their fingers that it's the right time to do so. This is a terrible state of affairs.

Because of Perl's automatic memory management, an object destructor is rarely needed in Perl. Even when it is, explicit invocation is not only uncalled for, it's downright dangerous. The destructor will be called by the run-time system when the object is no longer in use. Most classes don't need a destructor because Perl takes care of simple matters like memory deallocation.

The only situation where Perl's reference-based garbage collection system won't work for you is when there's a circularity in your data structure, such as:

$self->{WHATEVER} = $self;

In that case, you must delete the self-reference manually if you expect your program not to leak memory. While admittedly error-prone, this is the best we can do right now. Recipe 13.13 provides an elegant solution to this problem, however. Nonetheless, rest assured that when your program is finished, its objects' destructors are all duly called. At interpreter shutdown time, a second, more sweeping form of garbage collection is performed. Not even unreachable or circular objects can escape this final destruction. So you are guaranteed that an object eventually gets properly destroyed, unless a program never exits. If you're running Perl embedded in another application, the second GC pass happens more frequently  - whenever an interpreter shuts down.

DESTROY does not get called when a program exits via an exec call.