Software Development
February 2004
The thrill of independent effort soon pales when Jerry rains on Alphonse’s parade. Painfully, our apprentice realizes the bitter truth—and pushes the delete key.
By Robert C. Martin
I returned to the lab after lunch, but Jean wasn’t there—no note, no e-mail,
and her knitting basket was nowhere to be seen. After waiting a few minutes, I
sat down and continued working on the SMCRemoteServer
.
So far the server didn’t serve anything—it was just a couple of functions
that built and executed the SMC command line. It seemed reasonable that the
server code should open a socket and accept connections from the
SMCRemoteClient
that we wrote earlier.
I was still pretty steamed about our pace. We’d worked all morning and had
written only two small functions and their attendant unit tests. Champing at the
bit, I grabbed the keyboard. “First,” I thought, “this server needs to serve
something—let’s use the SocketServer
class that Jerry and I built
last week.”
Getting the server to serve was pretty simple. I just needed to write a
constructor that created a SocketService
object and passed in a
SocketServer
—then the SocketServer.serve
method would
automatically be called as soon as SMCRemoteClient
tried to
connect.
I looked in the SMCRemoteClient
code and saw that the client
expects a string to be sent upon connection. That string should begin with SMCR,
I reasoned, so I wrote that string in the serve()
method.
Next, the server needed to read a CompileFileTransaction
from
the client. It needed to write the files contained in that transaction, invoke
the compiler and then return the resulting files in a
CompilerResultsTransaction
. This didn’t seem like a hard thing to
write, so …
Hmmm … Compiling the file didn’t seem very difficult, but what output file
should I put into the result transaction? What’s its name? Jean had coached me
in writing a test for invoking a compile, so I looked at that test and found
that the input file had a .sm
suffix and the output file had a
.java
suffix. So all I had to do is replace .sm
with
.java
in the filename.
This should work. All I needed to do was to start the server and run the
client—simple! So I created a source file in my directory named
F.sm
, just like the one that Jean had me create in the morning.
Then I wrote a simple main function in SMCRemoteServer
.
Finally, I ran it. It just hung there, waiting for a client to connect. Now this was exciting! I ran the client with F.sm as its argument—and it RAN! Well, it exited after several seconds with a normal exit code, and without any error messages, either from the client or the server. Cool!
But what had it done? I couldn’t tell. So I checked the directory and found
an F.java
file sitting there! It had the right date on it, so it
must have been created by my run of the client. Way cool! I opened the file and
it looked like generated Java code. It even said it was generated by SMC. My
code worked!
It had been a couple of weeks since I had felt this good; since before I started working here, as a matter of fact. This was what programming was all about! I was filled with the rush of getting code to work. I was invincible! I got up and did a little jig around my seat.
Jerry must have been nearby, because he walked into the lab with a wry smile
on his face. “Hey, Alphonse,” he asked. “What’re you celebrating?” “Oh, hi,
Jerry! Look at this! I just got the SMCRemoteServer
working!”
“Really? That’s great, Alphonse.” He had a funny look on his face—as if he
didn’t believe me. So I showed him how the server was sitting there running. I
ran the client again. I showed him that an F.java
file with the
right date was created. I even showed him that it contained generated Java
code.
Jerry looked at me skeptically, and then glanced nervously at the door. “Alphonse, where are your tests?” he asked. “Jerry, you don’t need unit tests for something this simple,” I blustered, a bit miffed that he seemed so nonplussed. “Look, it was just a dozen lines of code or so. Jerry, I made progress here. I got something done. And it didn’t take all day! You guys waste so much time on all those unit tests!”
Jerry just stared at me for a few seconds, as if he couldn’t quite process what I was saying. Then he shut the door to the lab and sat down. “Alphonse, has Jean seen this?”
“No, she hasn’t come back from lunch yet,” I answered impatiently. “What’s the matter?” “Delete it, Alphonse.” “Delete what?” I squeaked. “Delete the code you just wrote,” Jerry replied evenly. “It’s worthless.”
I’d half expected this kind of reaction from someone, but it still hurt. I
rolled my eyes and said, “Oh, come on, Jerry! It works! How could it be
worthless?” “Are you sure it works, Alphonse?” he asked. “You saw it for
yourself!” I blustered. “The
file is proof!”
“Proof, eh?” Jerry raised an eyebrow. “Alphonse, why is the date of the
F.java
F.sm
file exactly the same as the date on the
file?”F.java
“What?” I looked at the directory, and sure enough, they were identical to
the second—and that didn’t make any sense. I had written the F.sm
file by hand several minutes ago. Why did it have the same date as the
file that was created seconds ago when I
demonstrated the system to Jerry? I stared at it for awhile, and then admitted
that I didn’t know.F.java
“Delete the code, Alphonse,” Jerry repeated, a bit more urgently this time. “You don’t understand it.” “Aw, come on, Jerry, I understand it,” I smiled. “I—I just can’t figure out why the dates don’t look right. It works, Jerry … it works.” But I wasn’t so sure any more. Why was that date different?
“Alphonse, by any chance did you happen to run the client and server in the same directory?”
“Uh …” I hadn’t specified a different directory for them, so I guessed they must have been running in the same place. “I guess so.” “So the client and the server were both reading and writing the same files in the same directory?” Jerry went on inexorably.
The light began to dawn and my stomach started churning. “Oh …” Jerry nodded grimly. “Yeah.”
I shook my head. “OK, Jerry, you’ve got a point. I don’t understand
everything that’s going on. But look, there’s an F.java
file there.
Something had to be working!”
“So what? You don’t know what is and what isn’t working. You don’t understand
what you’ve done. The things that appear to be working may be working by
accident. Is it possible, for example, that that F.java
file was
left over from a previous unit test?”
It was possible! Yikes, Jean and I had caused the system to write an
F.java
file just this morning! “Damn!” I bit my lip, but made a
last-ditch effort to salvage those few moments of ecstasy. “Yes, it’s possible
but it’s not very likely!” But even I knew it wouldn’t wash. “Delete the code,
Alphonse,” Jerry repeated tersely. “It’s crap.”
I just stared at him. I had made progress, damn it! Now he wanted me to wipe it all out. But he was right—I didn’t understand this code, and I had no tests that would demonstrate, step by step, that everything was working as it should. If my code was working (and now I was starting to wonder), it was more by accident than by design.
“Delete the code,” Jerry said, with an edge in his voice this time. “You don’t want Jean to see this. Right now she thinks the world of you, and this would be very disappointing for her.”
My resolve finally failed. Suddenly, I realized I cared about what Jean thought of me. Still, it hurt to realize that my brief solo flight must end in a crash landing. My shoulders fell, my head hung, and I reached over and deleted the code.
Without another word, Jerry walked out of the room, shaking his head.
A few moments later, Jean walked in. “Hello Alphonse, dear. I’m sorry I’m late, but I got into a conversation with an old friend of mine who brought out some new pictures of her great-grandchildren. Well, I couldn’t resist that, could I, dear? I love showing pictures of my great-great-grandchildren. Have you seen them, dear? Oh, I’ll save them for later—we’ve got work to do, you and I. What have you been up to this morning?”
“Nothing, Jean,” I forced a wan smile. “I was just waiting for you.”
To be continued …
Click here to download additional source code for this article.
Click here for past episodes and code listings.