12 PUTTING A SYSTEM TOGETHER
This discussion has focused so far on individual classes. This is consistent
with the Eiffel method, which emphasizes reusability and, as a consequence,
the construction of autonomous modules.
To execute software, you will need to group classes into executable
compounds. Such a compound is called a system -- the Eiffel concept
closest to the traditional notion of program -- and is defined by the following
elements:
- 1 A set of classes, called a universe.
- 2. The designation of one of these classes as the system's root
class.
- 3. The designation of one of the creation procedures of the root class
as the root creation procedure.
To execute such a system is to create one direct instance of the root
class (the root object for the current execution), and to apply
to it the root creation procedure -- which will usually create other objects,
call other routines and so on.
For simplicity and conformance to the method (which uses the class as
the fundamental form of module) ISE Eiffel assumes that you store the text
of each class in a separate file, called its class file. The default convention
is to use file names of the form name.e. For clarity, name
should normally be the class name, but because DOS and Windows limit file
names to 8 characters (plus the extension) you may have to truncate that
name, for example by storing a class BINARY_SEARCH_TREE into a file
called binstree.e.
The Eiffel method also suggests grouping related classes -- typically
5 to 40 classes -- into collections called clusters. Since each
class is stored in a file, it is natural to associate each cluster with
a directory.
These observations yield the mechanism that you will use to specify
a universe (item 1 in the above list): you specify a list of directories,
which yields a list of clusters; the classes contained in the .e
files of the directories constitute the universe.
The classes of a system will include its root class and all the classes
that it needs directly or indirectly, where a class is said to need
another if it is one of its heirs or clients.
To specify a system you will need to state, in addition to the list
of directories, the name of the root class (which must be one of the classes
of the universe) and of the root creation procedure (which must be one
of the creation procedures of the root class).
Here is an example of such a system specification. This text is not
written in Eiffel, although it definitely has an Eiffel-like flavor. It
is called an Ace (for Assembly of Classes in Eiffel) and is written in
a notation called Lace (Language for the Assembly of Classes in Eiffel).
As elsewhere in this book, the vertical bar character | is a placeholder
for the path separator used on your operating system; replace it by / on
Unix, \ on Windows, or the equivalent convention for specifying path names
on VMS and other platforms.
- system
- example
- root
- CALCULATOR (my_cluster1): "make"
- default
- assertion (ensure);
- precompiled ("$EIFFEL5|precomp|spec|$PLATFORM|base")
- cluster
- my_cluster1: "mydir|project1|subdir";
- her_cluster2: "herdir|project2|subdir1|subdir2"
- end
You will need an Ace to compile any system, but except for advanced
uses you do not have to learn the details of Lace, which are simple anyway:
the installation contains plenty of example Aces that you will be able
to copy and adapt for your own use. Look in particular in the examples
subdirectory of the delivery directory.
The subset of Lace illustrated by the above Ace suffices for basic uses
of Eiffel. The system clause gives
a name to the system, here example; the environment will use this
name for the executable file generated as the result of compilation. The
root clause gives the name of the root
class, here CALCULATOR, and its creation procedure, here make;
the name of the cluster to which CALCULATOR belongs, appearing in
parentheses, is optional if no other cluster contains a class of that name.
This Ace, by the way, is adapted from a small digital calculator system,
one of the examples included in the delivery -- hence the name of the root
class.
The clusters themselves are specified in the last clause, cluster,
here listing only two clusters, each with a cluster name (my_cluster1,
her_cluster2) and the associated directory in double quotes. The
cluster name, an identifier, will be used to refer to the cluster elsewhere
in the Ace, for example here in the reference to my_cluster1 appearing
in the root clause as seen above. A
system may have as many clusters as desired.
The default clause serves to specify
compilation options. The above Ace relies on the EiffelBase library, precompiled;
hence the precompiled clause, which
specifies the standard directory for storing this library, as explained
in more detail in the COMPILE.TXT on-line document). Because of the presence
of EiffelBase, with its dozens of clusters, a system with such an Ace as
above might actually be a significant system even with just two clusters
of its own.
The other compilation option specified above is assertion
(ensure) which states that
the generated code must at run time monitor assertions up to the postcondition
(ensure) level. The possible levels
include require (preconditions only,
the default), ensure and invariant;
each of them implies the previous ones.
You can also specify various levels of assertion monitoring separately
for a cluster, or for a specific class. For details, see the full description
of Lace: appendix D of the book Eiffel:
The Language

|