Blessed file handles aren't counted by PL_sv_objcount This seems to be by design, as it's all quite explicit in the source. The upshot is that if you attempt to avoid "unnecessary" work during destruction:
==== //depot/perl/sv.c#946 - /home/nick/p4perl/perl/sv.c ==== --- /tmp/tmp.7324.0 Sat Jul 2 20:14:56 2005 +++ /home/nick/p4perl/perl/sv.c Sat Jul 2 18:52:57 2005 @@ -494,8 +494,10 @@ Perl_sv_clean_objs(pTHX) PL_in_clean_objs = TRUE; visit(do_clean_objs, SVf_ROK, SVf_ROK); #ifndef DISABLE_DESTRUCTOR_KLUDGE - /* some barnacles may yet remain, clinging to typeglobs */ - visit(do_clean_named_objs, SVt_PVGV, SVTYPEMASK); + if (PL_sv_objcount) { + /* some barnacles may yet remain, clinging to typeglobs */ + visit(do_clean_named_objs, SVt_PVGV, SVTYPEMASK); + } #endif PL_in_clean_objs = FALSE; } then tests fail: op/ref.t 89 1 1.12% 71 run/fresh_perl.t 94 1 1.06% 53 Notably both these tests have their own little hacks to ensure that the destructor gets called at all: op/ref.t test 71: # using a regex in the destructor for STDOUT segfaulted because the # REGEX pad had already been freed (ithreads build only). The # object is required to trigger the early freeing of GV refs to to STDOUT like (runperl( prog => '$x=bless[]; sub IO::Handle::DESTROY{$_="bad";s/bad/ok/;print}', stderr => 1 ), qr/^(ok)+$/, 'STDOUT destructor'); run/fresh_perl.t test 53: ######## package X; sub any { bless {} } my $f = "FH000"; # just to thwart any future optimisations sub afh { select select ++$f; my $r = *{$f}{IO}; delete $X::{$f}; bless $r } sub DESTROY { print "destroyed\n" } package main; $x = any X; # to bump sv_objcount. IO objs aren't counted?? *f = afh X; EXPECT destroyed destroyed Isn't the current behaviour a bit of a bodge? Why is it this way? Nicholas Clark