Contents

4.4 The Line Tool

Meridian now has an Ada Development Interface (ADI) that integrates a smart editor with the compiler. If you compile a file that has error in it, you can push a button and the cursor will move to the point in the source code where the next error is. AdaVantage Version 1.5 didn't have that feature. If you compiled a file that contained errors it would write a message to the screen telling you that line number X in SOMEFILE.ADA contained a certain error. You could call up the EDLIN editor and go to line X to see what it was. Sometimes the error was really in line X-1 (a missing semicolon, for example), and the compiler didn't recognize the error until line X. Sometimes the error was many lines earlier. (For example, proper use of a variable that was improperly declared generates an error message pointing to the line using the variable, not the line declaring it.)

I decided I would like to be able to type LINE X SOMEFILE.ADA and see that line on the screen. The more I thought about it, the more I realized I really wanted to see a few lines before and after line X. So, I wrote the Line program shown in Listings 63 and 64.

Although the Line program was written in response to a specific need (to display lines containing errors), it isn't limited to that single use. You can use it to browse through any file for any reason.

4.4.1 Multiple Arguments

The Line program needs two arguments on the command line (a line number and a file name). The Extract subunit extracts these two pieces of information from the command line and returns them as separate parameters. This forced me to make some design decisions. Which argument should come first? What should I do if the user enters the arguments in the wrong order?

My first reaction was that the file name should be the first argument and the line number should be the second one. This makes sense from a programmer's point of view because the file has to be opened before the program can start looking for a particular line. It also seemed consistent because More and Write both have filenames immediately following the command.

I wrote the Extract routine to take the file name first, used the program for a while, and found I kept making mistakes. If I wanted to see line 15 of SOMEFILE.ADA, I naturally typed LINE 15 SOMEFILE.ADA. It seemed wrong to type LINE SOMEFILE.ADA 15. (Since it's usually right to not split an infinitive, analogy suggests that I shouldn't separate 15 from LINE.) From a user's point of view, it makes more sense from a user's point of view to put the line number first, so I changed the order in Extract.

4.2.2 Error Tolerance

I put the arguments in the order that seems right to me. Who's to say that every user will feel the same way. It may be natural for them to put the file first. They may naturally enter the arguments in the wrong order. That's an easy error to detect. Only one of the fields will be the image of an integer, so that field must contain the line number. If the program detects the incorrect entry, the program could respond with this error message, "You have entered the arguments in the wrong order. The correct syntax is LINE N FILENAME.EXT."

The user might respond to this error message with a respectful genuflection, and say, "Oh, I'm so sorry. Please forgive me. I promise never to make that mistake again." Users like that may exist, but I've never found one. Most users will say, "If you're so darn smart, and know that the arguments are reversed, why don't you just do what I want?" The point is well taken. If a program is smart enough to recognize the error, and can tell the user exactly how to correct it, can't it just as well be smart enough to fix the error itself?

This kind of tolerance is almost unknown in user interfaces, but perhaps the Line program may start a trend. Instead of insulting the user, it simply complies with any poorly stated command. If the user enters the two arguments in the correct order, it works. If the user enters the two arguments backwards, it works. If the user forgets to enter the file name, it asks for the file name. If the user forgets to enter the line number, it asks for the line number. If the user doesn't enter either, it asks for both. There's no need to be nasty when its so easy to be nice.

4.4.3 Presuming Too Much

If a software component is going to be reusable, it can't presume too much about how it will be used. A case in point is the Get_Command_Line procedure for the Meridian system. It presumes too much and that makes it awkward to use.

The Alsys and DEC versions of Get_Command_Line are built on general routines that return the whole command line. Alsys and DEC didn't make any assumptions about how anyone would want to use the command line. They just give you the command line and let you do whatever you want with it.

Meridian assumed that anyone who wants the command line will want to break it down into individual arguments, so they tried to do the programmer a favor and split it apart for him. Their ARG package tells you how many arguments there are, and passes an array of arguments back. That's really handy if that's exactly what you want to do. If it isn't then it is clumsy.

I've written a routine that doesn't appear in this book (because it doesn't teach any new lessons) called Search that searches a file for a text string. It is invoked by the command SEARCH FILENAME.EXT "A STRING WHICH MAY CONTAIN PUNCTUATION, SPACES, AND WHO KNOWS WHAT ELSE!". The Meridian ARG package returns this as 13 individual arguments, but there are really only two (FILENAME.EXT and the text string). I have to go to the trouble to put together the things that Meridian has taken apart.

That's not a terrible ordeal. Listing 65 shows how to do it. It's inefficient for ARG to take apart the command string and then make Get_Command_Line put it back together so Line.Extract can take it apart again, but that's the price you pay for portability if you make your utility routines too specific.


Contents | Next ...