Документация
HTML CSS PHP PERL другое

Section 13.1.  Cleaning Up After Yourself

 
Previous
Table of Contents
Next

13.1. Cleaning Up After Yourself

Suppose our object uses a temporary file to hold data that won't fit entirely in memory. The object can include the filehandle for this temporary file in its instance data. While the normal object destruction sequence will properly close the handle, we still have the temporary file on disk unless we take further action.

To perform the proper cleanup operations when an object is destroyed, we need to know when that happens. Thankfully, Perl provides such notification upon request. We can request this notification by giving the object a DESTROY method.

When the last reference to an objectsay, $bessiedisappears, Perl invokes that object's DESTROY method automatically, as if we had called it ourselves.

$bessie->DESTROY

This method call is like most other method calls: Perl starts at the class of the object and works its way up the inheritance hierarchy until it finds a suitable method. However, unlike other method calls, there's no error if Perl doesn't find a suitable method.[*]

[*] Normally, our own method calls will cause an error if Perl doesn't find them. If we want to prevent that, we just put a do-nothing method into the base class.

For example, going back to the Animal class defined in Chapter 11, we can add a DESTROY method to know when objects go away, purely for debugging purposes:

## in Animal
sub DESTROY {
  my $self = shift;
  print '[', $self->name, " has died.]\n";
}

Now when we create any Animals in the program, we get notification as they leave. For example:

## include animal classes from previous chapter...

sub feed_a_cow_named {
  my $name = shift;
  my $cow = Cow->named($name);
  $cow->eat('grass');
  print "Returning from the subroutine.\n";    # $cow is destroyed here
}
print "Start of program.\n";
my $outer_cow = Cow->named('Bessie');
print "Now have a cow named ", $outer_cow->name, ".\n";
feed_a_cow_named('Gwen');
print "Returned from subroutine.\n";

This prints:

Start of program.
Now have a cow named Bessie.
Gwen eats grass.
Returning from the subroutine.
[Gwen has died.]
Returned from subroutine.
[Bessie has died.]

Note that Gwen is active inside the subroutine. However, as the subroutine exits, Perl notices there are no references to Gwen; it automatically invokes Gwen's DESTROY method, printing the Gwen has died message.

What happens at the end of the program? Since objects don't live beyond the end of the program, Perl makes one final pass over all remaining data and destroys it. This is true whether the data is held in lexical variables or package global variables. Because Bessie is still alive at the end of the program, she needs to be recycled, and so we get the message for Bessie after all other steps in the program are complete.[*]

[*] This is just after the END blocks are executed and follows the same rules as END blocks: there must be a nice exit of the program rather than an abrupt end. If Perl runs out of memory, all bets are off.


Previous
Table of Contents
Next
© 2000- NIV