I read the "Programming Perl" book which is rather complicated in some places. And one of those places is the section "Instance Destructors" in the 12th chapter "Objects". This section says:
DESTROY
method in its class.Then there is a paragraph which I failed to understand:
This only applies 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 ag- gregation (sometimes called a “has-a” relationship) is often cleaner and clearer than inheritance (an “is-a” relationship).
I can't understand what it means. Does it mean that an object that IS NOT simply contained within the current object, WILL NOT be freed and destroyed automatically?
I do know that a DESTROY
that is called on the garbage collection is the nearest one and only one. No other overridden DESTROY
methods are called when there is no refs to an instance. But, as I understand, the same behavior is expected when a ref to an instance is placed inside another object.
Would someone be so pleasant to construe and to provide a code-example ?
UPDATE:
Actually what I was looking for, was the explanation of the This only applies to inherited classes; words which turned out to be that:
If you have an instance of a class and it has a DESTROY
method than that method will override DESTROY
methods of a parent class(es), but that does not apply to an object, that is in a has-a
relationship with the object in question. Its DESTROY
won't be overridden
Sorry for not clear question, it would better fit to the English Language and Usage. Thanks to everyone.
{
my $object = Class->new()
}
# there are no more references to $object
# (it is out of scope and can't be accessed by any means)
# Perl is free to garbage-collect it.
package Class;
sub new { return bless({}, shift) }
sub DESTROY { print STDERR "The object is destroyed" }
####
{
my $object = Class->new();
}
# before the object is garbage-collected, cleanup-operations should be manually performed
# like closing down connections, solving circular references
# any time, the object might print it's message.
package AnotherClass;
use Class;
use parent 'Class';
sub DESTROY { print STDERR "subclass reporting dead" }
Now if AnotherClass
will be instantiated, only the DESTROY
method of AnotherClass
will be called, not the DESTROY
method of Class
. This is meant with the absence of a hierarchical destruction. This is obvious, as the DESTROY
method overwrites the previous entry. The original DESTROY
can be called manually
Using a parent class and a child class is a IS-A relationship: AnotherClass
is a Class
.
If we have YetAnotherClass:
package YetAnotherClass;
use Class;
sub new {return bless({member => Class->new()}, shift) }
{
my $object = YetAnotherClass->new();
}
# $object goes out of scope (zero reference count) and will be destroyed.
# Therefore, the reference count of the "member" drops to zero
# The member will therefore be destroyed and print it's message.
This is a case of aggregation (Class
is a data member of YetAnotherClass
), and a HAS-A relationship.