This is a bug in perl which will be fixed in 5.22 (see Leon's comment below).
This happens because undef $f;
doesn't actually free up and destroy $f
, it just marks it as ready to
be freed by a nextstate
op.
nextstate
ops exist roughly between each statement, and they are there
to clean up the stack, among other things.
In your example, since undef $f
is the last thing in the file, there
is no nextstate after it, so your local destructor goes out of scope
before $f
's destructor is called (or, the global destruction that
happens just isn't aware of your local change.)
When you add a print statement after undef $f
, the nextstate
op
before the print calls your local destructor.
You can see the additional nextstate
in your example at
https://gist.github.com/calid/aeb939147fdd171cffe3#file-04-diff-concise-out.
You can also see this behaviour by checking caller()
in your DESTROY
method:
sub DESTROY {
my ($pkg, $file, $line) = caller;
print "Destroyed at $pkg, $file, $line\n";
c();
}
mhorsfall@tworivers:~$ perl foo.pl
Destroyed at main, foo.pl, 0
IN DESTROY
IN ORIG C
mhorsfall@tworivers:~$ echo 'print "hi\n"' >> foo.pl
mhorsfall@tworivers:~$ perl foo.pl
Destroyed at main, foo.pl, 30
IN DESTROY
IN MY C
hi
(Line 30 being the print "hi\n"
)
Hope that sheds some light on this.
Cheers.