In the code snippet below, the object of class Foo
contains a reference to an object of class Bar
. I would expect that the Foo
object is destroyed before the Bar
object. Unfortunately, this doesn't always happen. Strangely enough, I get different behaviors on differenct systems: on my laptop and desktop, the code always runs correctly, whereas on 2 VPSs that I tried, the destructors are ran in reverse order (most of the time). All four systems run the same version of perl (5.20.2 on x86_64 linux).
Also, this only happens when a sub (called abcd
below) contains a reference to the Foo
object. If I remove that, the problem goes away.
#!/usr/bin/perl
use strict;
use warnings;
my $foo = Foo->new;
sub abcd {
$foo;
}
####################
package Foo;
sub new {
bless {bar => Bar->new}, 'Foo';
}
sub DESTROY {
my ($self) = @_;
defined $self->{bar} or print "bar is undefined, this should not happen\n";
}
####################
package Bar;
sub new {
bless {}, 'Bar';
}
When it comes to global destruction, which happens as the program is exiting, perlobj
is clear
The order in which objects are destroyed during the global destruction before the program exits is unpredictable.
This is clearly the case without the sub abcd
in your posted test program. With the sub, the last reference to the object is inside the sub so it reaches the global destruction as well. (I also get different behavior in the two cases, but this is meaningless given the above quote.)
Thus in both cases, with or without the sub, the objects are destroyed in an unpredictable order.
When an object is destroyed because the last reference to it went out of scope, things are different. To see such behavior we can add undef $foo;
as the last line, to trigger controlled destruction
my $foo = Foo->new;
undef $foo;
END { say "END block." }
sub abcd { $foo; }
This results in Foo
being destroyed first, with and without the sub. It also happens before the END
block and before the global destruction phase. (Add prints to DESTROY
in Foo
and Bar
to see.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With