The fun part is the destructor. Let's take the
reference to ourselves, display a debugging message about the
particular barn being destroyed, and then ask for the name of each
inhabitant in turn. In action, this would be:
my $barn = Barn->new;
$barn->add(Cow->named("Bessie"));
$barn->add(Cow->named("Gwen"));
print "Burn the barn:\n";
$barn = undef;
print "End of program.\n";
This prints:
Burn the barn:
Barn=ARRAY(0x541c) is being destroyed...
Bessie goes homeless.
Gwen goes homeless.
[Gwen has died.]
[Bessie has died.]
End of program.
Note that the barn is destroyed first, letting you get the name of
the inhabitants cleanly. However, once the barn is gone, the
inhabitants have no additional references, so they also go away, and
thus their destructors are also invoked. Compare that with the cows
having a life outside the barn:
my $barn = Barn->new;
my @cows = (Cow->named("Bessie"), Cow->named("Gwen"));
$barn->add($_) for @cows;
print "Burn the barn:\n";
$barn = undef;
print "Lose the cows:\n";
@cows = ( );
print "End of program.\n";
This produces:
Burn the barn:
Barn=ARRAY(0x541c) is being destroyed...
Bessie goes homeless.
Gwen goes homeless.
Lose the cows:
[Gwen has died.]
[Bessie has died.]
End of program.
The cows will now continue to live until the only other reference to
the cows (from the @cows array) goes away.
Let's alter the
Barn to Barn2 to illustrate
this:
{ package Barn2;
sub new { bless [ ], shift }
sub add { push @{+shift}, shift }
sub contents { @{+shift} }
sub DESTROY {
my $self = shift;
print "$self is being destroyed...\n";
while (@$self) {
my $homeless = shift @$self;
print " ", $homeless->name, " goes homeless.\n";
}
}
}
Now use it in the previous scenarios:
my $barn = Barn2->new;
$barn->add(Cow->named("Bessie"));
$barn->add(Cow->named("Gwen"));
print "Burn the barn:\n";
$barn = undef;
print "End of program.\n";
This produces:
Burn the barn:
Barn2=ARRAY(0x541c) is being destroyed...
Bessie goes homeless.
[Bessie has died.]
Gwen goes homeless.
[Gwen has died.]
End of program.
As you can see, Bessie had no home by being booted out of the barn
immediately, so she also died. (Poor Gwen suffers the same fate.)
There were no references to her at that moment, even before the
destructor for the barn was complete.