Aristotle has asked for the wisdom of the Perl Monks concerning the following question:
My basic scenario is like so:
sub something { # ... open my $fh, '>', $_[0] or die "Couldn't open $_[0] for writing\n"; # ... }
Note that I’m not explicitly closing the filehandle. When execution leaves the subroutine (or loop or naked block or whichever kind of scope it is), the filehandle goes falls into limbo and is picked up by the garbage collector, which automatically closes the handle before disposing of the glob.
The problem is that close can actually fail (the canonical case is when there are write buffers left to flush but the disk has filled up). So therefore, you should always check the return value of close, at least on files you have opened for writing (whereas for files you have only opened for reading, there is very little point in caring). But when the garbage collector disposes of a filehandle, it ignores that return value. So I end up having to litter my code with explicit close calls anyway, just when I thought I could let the scope structure of the code implicitly define the scope of open files.
So I wonder if there is a way to get perl to throw an exception when it tries to close a filehandle in the garbage collector and gets an error. Most of the time, that’s what I want anyway, since there isn’t much in the way of automatic recovery that can be done on failure to close a file, and the condition is usually indicative of some serious administrative issue, so the only sensible response is to die screaming bloody murder at the user.
In the simplest case, use Fatal qw( :void close ); would work for this, but I strongly doubt it, and in any case I can’t think of a good way to purposefully trigger a close failure in order to test it.
(Note: in the chatterbox it was suggested to check $! just after the block, after clearing it just before the end of the block, but that’s really pretty pointless. For one thing, it’s imprecise: there might be several filehandles or objects or tied variables going out of scope, any of which may set $!. Worse, though, it trades one line of manual cleanup code that can be placed within the block for several lines that need to be strewn across several scopes – so I wouldn’t gain anything even if it worked in the first place.)
Makeshifts last the longest.
|
|---|