Is there a way to report how many open file handles are open at once so I can know when I'm being wasteful?

Umm... yes, but for now it is - well, a hack.

This is a splendid use for inside-out objects, where information about an object is stored in the class which deals out the instances. That way you can ask the class about the state of any known object, if the class provides automatic garbage collection of objects that go out of scope. Perl includes a wonderful inside-out object class which does just this for any class: Hash::Util::FieldHash, based on Alter written by anno.

You would need to use modules from the IO family to initialize your file handles, consequently. That way your filehandles become objects and can be registered within the class.

The following is a quick hack, monkey-patching IO::File, but if it would be incorporated into IO::File, it would add 2 lines of code at the top level, 1 line of code in each of the methods new and open, and two class methods: open_fds and known_fds to query the class. In fact, known_fds would suffice, if it returns the objects which can then be queried further, but that can lead to more leakage if the variables holding the objects aren't freed.

This is for IO::File only; adapting this abomination to other modules of the IO family is left as an excercise for the reader ;-)

# file io-open-hack.pl use strict; use warnings; use IO::File; BEGIN{ package IO::File { use Hash::Util::FieldHash qw(id_2obj); Hash::Util::FieldHash::fieldhash my %fh; *IO::File::_new = \&IO::File::new; *IO::File::_open = \&IO::File::open; { no warnings 'redefine'; *IO::File::new = sub { my $io = &_new; $fh{$io} = { new => "@{[caller]}" }; $io; }; *IO::File::open = sub { my $io = $_[0]; $fh{$io}->{open} = "$_[1] at @{[caller]}"; &_open; }; } sub open_fds { grep { $_->{fh}->opened } known_fds(); } sub known_fds { map { { new => $fh{$_}->{new}, # next is dubious, it leaks the object... fh => id_2obj($_), # ... so we should return it stringified? #fh => "@{[id_2obj($_)]}", open => $fh{$_}->{open}, } } keys %fh; } } } package main; use IO::File; { my $fh = IO::File->new(); $fh->open( "blorfldyick",'>'); print $fh "foo\n"; print "after open:\n"; report_fds($_) for qw(open known); close $fh; print "after close:\n"; report_fds($_) for qw(open known); } # $fh is out of scope here print "after scope:\n"; report_fds($_) for qw(open known); sub report_fds { my $type = shift; my $meth = "${type}_fds"; my @fds = IO::File->$meth(); print " $type files:"; if (@fds) { print $/; print " fh: $_->{fh}\n" . " new: $_->{new}\n" . " open: $_->{open}\n" for @fds; } else { print " none\n"; } } __END__ after open: open files: fh: IO::File=GLOB(0x137a3b8) new: main io-open-hack.pl 45 open: blorfldyick at main io-open-hack.pl 46 known files: fh: IO::File=GLOB(0x137a3b8) new: main io-open-hack.pl 45 open: blorfldyick at main io-open-hack.pl 46 after close: open files: none known files: fh: IO::File=GLOB(0x137a3b8) new: main io-open-hack.pl 45 open: blorfldyick at main io-open-hack.pl 46 after scope: open files: none known files: none

This feature could be off by default and turned on inside IO::File via a debug import tag or some such.

perl -le'print map{pack c,($-++?1:13)+ord}split//,ESEL'

In reply to Re: A way to report open file handles a Perl script has open? by shmem
in thread A way to report open file handles a Perl script has open? by nysus

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.