[Previous:FW: cyberpunk parody (fwd)]
[Next:Fw: best thing I've seen all week]
[Main Index]

hard reference problem

01/10/2002


In article <32O586Q5.2678@znvy.t440.pbz>, Nick Bauman  <avpx@t440.pbz> wrote:
>Here is my problem code snippet:
>
>open(EMPLOYEES,'<+/usr/local/etc/httpd/g440/cgi-bin/perl_lib/emp.asc');
>my $Fh = locksmith(\*EMPLOYEES,\*lockType,\*lookIt);
>
>The problem arises in my referencing the passed filehandle EMPLOYEES in
>and out of locksmith, I think. The while (<$Fh>) { } never actually
>runs. Why? I've checked the obvious;

NO, YOU HAVEN'T.  

Years ago one of our student programmers asked me what the secret of
my programming success was.  I told him, and now I will tell you.
Come close, so I can yell in your ear.  There are actually two
secrets.  The first secret is:

	NEVER 
	NEVER
	NEVER MAKE A SYSTEM CALL WITHOUT CHECKING FOR AN ERROR RETURN

Oh, sure.  I hear you scoffing, maybe chuckling indulgently.  Some
secret, you say.  Everyone knows THAT.  Well, if everyone knows that,
how come nobody DOES it?  <poke> How come YOU didn't do it?  <poke>
Programmers who don't check the return from `open' get POKED.  <poke>
<poke> <poke>!

Now we're going to DO it.  You should take this:

   open(EMPLOYEES,'<+/usr/local/etc/httpd/g440/cgi-bin/perl_lib/emp.asc');

and write it this way:

   $FILE = '/usr/local/etc/httpd/g440/cgi-bin/perl_lib/emp.asc';
   open(EMPLOYEES, "<+ $FILE")
	or die "Couldn't open file `$FILE' for reading: $!; aborting";

Maybe something other than `die' is appropriate in your application;
we'll stick with `die' here.  Hey!  I want you to do this, NOW.  The
next paragraph is going to be my prediction about what is wrong, and
if you don't do it now, you won't get a chance to be impressed with my
precognitive abilities.  

		     EEENY, MEENY, MAGIC BEANIE!
		   THE SPIRITS ARE ABOUT TO SPEAK.

Hmmm, I the Great Dominus, predict that---wait as I gaze into my
crystal globule, it's becoming clear now---yes, I see a program, lying
dead in the snow.  But not of natural causes.  No, wait, it's
speaking, it's saying something, I strain to hear its dying words, and
yes, I hear it muttering

	Couldn't open file
	`/usr/local/etc/httpd/g440/cgi-bin/perl_lib/emp.asc' for
	reading: No such file or directory; aborting at line XXXX

Zounds, Watson!  We may not have found the killer, but now we have a
clue: the murder weapon.  The game is afoot!

Well, if it did say that, it would certainly narrow down your problem,
wouldn't it?  In particular, you could stop worrying about referencing
the passed filehandle and all that other stuff you mentioned, and
concentrate on the real problem, which is WHY IT COULDN'T FIND THE
FILE.  Personally, I dislike these sorts of problems much less than
abstruse ones about passing filehandle references.  ``The Case of the
Missing File'' sounds much more entertaining than ``The Mysteriously
Garbled Filehandle Reference.''  Also if you want to write a mystery,
you have to have a clue.  Now we have a clue.  Before all we had was
the muddy yard that Legrande and his policemen had been trampling
around in all morning.

Now comes the interesting part of the problem, which is figuring out
why it couldn't find the file.  Here it's hard to offer good advice,
because this is the part of the problem where it helps to have
experience and expertise, there's no big secret there, you just have
to practice, practice, practice.

If you don't have enough experience and expertise to recognize the
problem at this point, that doesn't reflect any discredit on you.
That's the point at which you come into the newsgroup, and instead of
a big hairy question like the one you asked, you get to say

	Subject:  `No such file or directory' when file exists?

	``Why does the `open' here

	   $FILE = '/usr/local/etc/httpd/g440/cgi-bin/perl_lib/emp.asc';
	   die "File `$FILE' did NOT exist; aborting"
		unless -e $FILE;
	   open(EMPLOYEES, "<+ $FILE")
		or die "Couldn't open file `$FILE' for reading: $!; aborting";

	  fail with `no such file or directory'?  I am sure that the
	  file does exist, because the program does not abort at the
	  preceding line.''

This is a lot more likely to get an answer than the question you did
ask.  I can't write these hundred-line treatises on elementary
debugging technique every time, you know.  Now you know why it's
important to make your mystery entertaining.  People aren't in here
for their health; they're here to entertain themselves.  They answer
entertaining questions.  You're lucky that I have a very weird idea of
entertainment.

Anyway, you probably would have gotten two or three responses from
people pointing out that the `perlfunc' man page says, under `open':

	You can put a '+' in front of the '>' or '<' to indicate that
	you want both read and write access to the file; thus '+<' is
	usually preferred for read/write updates--the '+>' mode would
	clobber the file first.

Hey, get that?  Maybe not; sometimes these things can stare you in the
face for days or even weeks before you see them.  The `+' goes *in
front*.  You meant `+<' and you wrote `<+'.  What you wrote, `<+ foo',
means to open a file named `+ foo' for reading only, so no wonder you
got `No such file or directory'.  The Case of the Missing File is
solved.

That does bring up the Second Big Secret, which is

	ALWAYS READ THE MANUAL

.  I hate to whack you with this, because you probably do read the
manual, but of course sometimes it's hard to know what to read, and I
do think this is one of those times.  But `open' is failing, and if
you did check the manual for `open' you might have seen the problem
yourself.  Then again maybe not.  Well, sometimes you see these
things, sometimes you don't.

These little typos can be hard to find sometimes.  I can't take too
much credit; I found it fast because my program had the same problem
yesterday.  But you're sure not going to find the typos if you don't
know where to start looking.  You have to start looking in the right
places!  Where you were looking, you were *never* going to find it.

What can we learn from this?  

99% of the programmers I have met use Professor Hill's `think method'
for debugging.  When the program fails, they guess what might be
wrong, and then they change the program at random until it appears not
to fail any more.  That's why the world is so full of cruddy software.
I am tired of cruddy software, so cut it the heck out already.

What you must do, instead, is include checks in your program.  (Even
for things that `can't happen'.)  If something doesn't check out,
print an error message. Then when (not `if') something goes wrong, you
can know where it was, and, if you have to guess, at least you can
confine your guesses to a very small part of the program.

I don't want to rule out the possibility that maybe there *was* a
problem in the part of the program you were examining it, but if there
is you are much more likely to find it if you know that the file is
actually open.

OK, now get out there and check those error returns!  Hut!

-- 

zwq@cbobk.pbz                                             Mark-Jason Dominus
zwq@cybire.pbz                              Plover Systems, Philadelphia, PA



pictures | bookmarks | people | -er jokes | pgp key | writings | band | resumé | .sigs | otp calculators | reference | dvorak | old
Mail converted by MHonArc 2.3.3