[sf-perl] Bad file number

Joe Brenner doom at kzsu.stanford.edu
Fri Jun 22 11:31:06 PDT 2007

Quinn Weaver <quinn at fairpath.com> wrote:
> Steve Fink wrote:
> > Quinn Weaver <quinn at fairpath.com> wrote:
> > > Loo, Peter # PHX wrote:

> > > > I have checked the logic and it appears that there is a
> > > > corresponding close() for every open().  I don't know why Perl is
> > > > warning me with this error.
> > >
> > > Just "checking the logic" by looking at your code doesn't cut it.
> > > You need to test empirically whether your code is doing what you think it is.
> > >
> > > Try putting warn "closed file MYFILE successfully" after your close
> > > statements... just to verify that what you think is happening is
> > > actually happening.
> > >
> > > Make a habit of testing your assumptions this way.  It is the royal
> > > road to figuring out bugs.  Debugging is a matter of practice, not theory--
> > > because if the code were working the way that you think in theory
> > > it should be, you wouldn't have a bug!
> > 
> > Good general advice, but I'm not sure how well it applies in this
> > situation. How many ways can close() fail
> Actually, I agree.  I think that placing warn statements after close
> (warn "just closed file $MY_PATH") will be more useful than checking
> the return code--because, as you pointed out, the most likely problem
> is that the close code is just failing to get called, due to bad logic.

Yes, most likely there's some hidden recursion in there again.  And
what I would do is trace it around in the debugger (if at all possible)
or just put in tracer debugging statements.  For example, you could try
inserting lines like these at the beginning of each sub:

    my $sub_name = ( caller(0) )[3];
    print STDERR "$sub_name called.\n";  # or "warn/carp", if you prefer.

Another thing that might be useful is to 

  use Carp qw( carp cluck croak confess);

You can use "cluck" to get your code to spit out stack backtraces.
And if you run your code like this: 

  perl -MCarp=verbose script.pl

you'll automatically get stack backtraces on your "carp"s and "croak"s.

But as for the question "How many ways can close() fail"?  
That beats me, I've never looked into it.  What happens if you close 
a file that's been deleted by another process?  Or if it was a symlink
that's been redefined in the meantime?  Or if it's on a partition that 
got filled up since it was opened?  Of if it's been flocked?
Or if it's ownership/permissions has changed? 

Conway, in his "Perl Best Practices" says: 

  "Never open, close, or print to a file without checking the outcome."

And I presume he's included "close" in the list for a reason. 

He also (later, in "Builtin Failures", ch 13) recommends the trick:

  use Fatal qw( open close ); 

So that you don't have to remember to "or croak" all over the place.

(I play around with this trick off and on and I would tentatively 
recommend it: I haven't noticed any problems with it, but Conway 
remarks that Fatal.pm works by "the use of dark and terrible magics", 
and coming from *him*, that's really scary.)

More information about the SanFrancisco-pm mailing list