The Amazing Address Book Program ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (public domain) version 0 Michael Sparks Introduction ~~~~~~~~~~~~ I have included two versions of this program, to show just how easy it is to add a Muse interface to your programs, how much easier it makes your programs to use, and to show how to use Muse in a more `data-processing' environment. It is also provided to show just how incidental the style of interface to your program should be. In an address book program, our main concern should be that our algorithms for manipulating names, addresses and telephone no.s etc work correctly and efficiently, not how we program a GUI. Since this is a totally made up example, I am not going to worry about implementing (or think about) implementing a large set of features or even a full set. I will however implement a representative sample. (addition, deletion, search, input, output) Program Overview ~~~~~~~~~~~~~~~~ Both versions have the same basic modular structure. They have a module that manipulates and compares individual records. A module that deals with the storage, retrieval and deletion of such records in such a way that does not depend on the internal format of the records. These two modules are the same for both programs. They do infact do all the hard work of the programs. There is also a module for each that deals with low-level control of the interface - eg clearing the screen/window, getting a record from the user, displaying a record etc, creating and displaying the interface and defining its look etc. Finally, there is the top-level module which uses these other modules. This acts as glue to enable the actions which can be performed on the data stored, to be intertwined with the interface for receiving and displaying of that same data. On a conceptual level, they are very similar in that they are the top-level functions that perform user requests. ie they react to inputs (and therefore events) from the user. Currently they look very different, but that is due to the fact that I *haven't* used a Muse-like program, for text interfaces. (eg lex+yacc) Operations involving low-level access on an Address Book record --------------------------------------------------------------- The first thing we need to know is the data we wish to store and a structure to store it. By this I mean what information about each address, not how we store many addresses - that's a different ball game. For this purpose I created an OBJECT called `person'. In a person we can store a name, telephone number and address (a short list of strings). For each person, we need to be able to set the name, telephone no and address, preferably only at creation time. This is implemented as the method mk(). We need any space allocated at run-time to be de-allocated at the time of the object's disposal. This is implemented in the object's standard end() method. Since we are propsing a search option for our address book program, we need to implement a _useful_ comparison function to compare two person objects. This is implemented as an umbrella method compare(). The reason I call it an umbrella method is because it is made up of three other comparison functions, all or one of which can be used at once. (in practice the application only uses the all at once part, but that in itself uses the other three parts, so its not a wasted effort. The comparison method does a string comparison between the stored person and the `checking field' passed to it. If that was all though, it wouldn't really be that useful since it would be case sensitive and _blanks_ sensitive. ie 'bla' and ' Bla' would be considered different. The comparison method used doesn't work that way. it checks to see if 'bla' exists *inside* ' bla ' rather than checking to see if they're identical. If it does, then it returns true, otherwise false. The null-string '' _is_ considered to exist in any string (just like the empty set is part of the power set of any set). This technique, although still case-sensitive, is MUCH more powerful than the basic `is it identical' approach. It allows us to search for all the (say) `Smiths' in a database just by putting `Smith' in the name field of the search person argument. This would match `Jo Smith', `John Smith', `Freda Smithers' and so on. I considered this useful since it allows us to put the bits of names and addresses that we *can* remeber when we're searching in the search fields, and let the program fill in the gaps. This enables us to search by example to pun a phrase... And that's that for the person module. The People Module ----------------- This is the second module. It is used to orgainise a collection of person objects into a single store that is easily accessible by a simple interface so that insertions, deletions and searches are straight forward. It does *not* care for the _structure_ of the data at all. In fact, it couldn't care less. The store is just an array (allocated at run-time) which can hold up to max_people elements which can be defined by the main program. (defaults to 100) It can perform the following actions: · Initialisation. · Insertions. · Deletions. · Define a search pattern (uses a person object). · Find a/next occurance of a search pattern (if defined). · Return the number of records stored. · Return the `current' record · Reset the `current' record pointer to the first record - if any. As you may infer from this list, the module keeps track of a `current' record much like the current position in a file using a file handle. Very primitive, but it works, reliably. Comment ~~~~~~~ The other two modules are covered in the directories of the two implementation styles since they are implementation style specific and described in enough general terms above.