This is a perl bug that will be fixed in 5.22 (see Leon's comment below).
This is because undef $f; doesn't actually release or destroy $f , it just marks it as ready to be freed with nextstate op.
nextstate ops exist between just about every statement, and they are there to clear the stack, by the way.
In your example, since undef $f is the last thing in the file, there is no next state after it, so your local destructor goes beyond $f destructor is called (or, global destruction, which is simply not known about your local changes.)
When you add a print statement after undef $f , nextstate op before printing calls your local destructor.
You can see an additional nextstate in your example at https://gist.github.com/calid/aeb939147fdd171cffe3#file-04-diff-concise-out .
You can also see this behavior by checking caller() in the 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 is print "hi\n" )
Hope this sheds light on this.
Greetings.
Matthew horsfall
source share