Update wikipage EiffelBase, The Kernel. (Signed-off-by:admin).

git-svn-id: https://svn.eiffel.com/eiffel-org/trunk@1464 abb3cda0-5349-4a8f-a601-0c33ac3a8c38
This commit is contained in:
eiffel-org
2015-11-24 10:13:50 +00:00
parent 6383121c1c
commit a5d1a7e9be

View File

@@ -1,30 +1,30 @@
[[Property:title|EiffelBase, The Kernel]]
[[Property:weight|0]]
[[Property:uuid|f6229125-dd7e-a50d-5b97-3ad7cd6071d5]]
[[Property:uuid|A26C5BCA-20A5-4EE6-9710-F4E8B72DBA10]]
In addition to basic concepts close to the language level, the Kernel covers such common needs as '''input''' and '''output''', '''storage''' and '''retrieval''' of objects on persistent storage, fine control over '''exception handling''' and '''memory management''', and access to '''operating system facilities'''. The kernel can be divided into 5 logical clusters of classes:
* The first cluster contains the universal class defining facilities accessible to all other classes: [[ref:/libraries/base/reference/any_chart|ANY]] . Every developer-defined class is a descendant of this class.
* The first cluster contains the universal class defining facilities accessible to all other classes: [[ref:libraries/base/reference/any_chart|ANY]] . Every developer-defined class is a descendant of this class.
* The second cluster includes classes whose facilities are directly related to language concepts:
** Classes describing the basic types: [[ref:/libraries/base/reference/boolean_chart|BOOLEAN]] , [[ref:/libraries/base/reference/character_8_chart|CHARACTER]] , [[ref:/libraries/base/reference/integer_32_chart|INTEGER]] , [[ref:/libraries/base/reference/real_32_chart|REAL]] and [[ref:/libraries/base/reference/real_64_chart|DOUBLE]]
** Arrays: class [[ref:/libraries/base/reference/array_chart|ARRAY]]
** Tuples: class [[ref:/libraries/base/reference/tuple_chart|TUPLE]]
** Strings: class [[ref:/libraries/base/reference/string_8_chart|STRING]]
** Basic facilities: class [[ref:/libraries/base/reference/basic_routines_chart|BASIC_ROUTINES]]
** Classes describing the basic types: [[ref:libraries/base/reference/boolean_chart|BOOLEAN]] , [[ref:libraries/base/reference/character_8_chart|CHARACTER]] , [[ref:libraries/base/reference/integer_32_chart|INTEGER]] , [[ref:libraries/base/reference/real_32_chart|REAL]] and [[ref:libraries/base/reference/real_64_chart|DOUBLE]]
** Arrays: class [[ref:libraries/base/reference/array_chart|ARRAY]]
** Tuples: class [[ref:libraries/base/reference/tuple_chart|TUPLE]]
** Strings: class [[ref:libraries/base/reference/string_8_chart|STRING]]
** Basic facilities: class [[ref:libraries/base/reference/basic_routines_chart|BASIC_ROUTINES]]
* The third cluster provides input and output facilities:
** [[ref:/libraries/base/reference/std_files_chart|STD_FILES]] offers basic mechanisms, sufficient for simple input and output.
** [[ref:/libraries/base/reference/file_chart|FILE]] describes the notion of sequential file, viewed as a sequence of characters and fully integrated in the data structure library.
** [[ref:/libraries/base/reference/directory_chart|DIRECTORY]] gives properties of directories (files serving as collections of other files).
** [[ref:libraries/base/reference/std_files_chart|STD_FILES]] offers basic mechanisms, sufficient for simple input and output.
** [[ref:libraries/base/reference/file_chart|FILE]] describes the notion of sequential file, viewed as a sequence of characters and fully integrated in the data structure library.
** [[ref:libraries/base/reference/directory_chart|DIRECTORY]] gives properties of directories (files serving as collections of other files).
* The next cluster, through class [[ref:/libraries/base/reference/storable_chart|STORABLE]] , makes it possible to store object structures on persistent storage and retrieve them later. This facility can also be used to transmit object structures through pipes or over a network.
* The next cluster, through class [[ref:libraries/base/reference/storable_chart|STORABLE]] , makes it possible to store object structures on persistent storage and retrieve them later. This facility can also be used to transmit object structures through pipes or over a network.
* The last cluster provides access to internal properties of the compiler and environment, useful for applications that need some fine-tuning of the basic mechanisms:
** Class [[ref:/libraries/base/reference/exceptions_chart|EXCEPTIONS]] (complemented by [[ref:/libraries/base/reference/unix_signals_chart|UNIX_SIGNALS]] for Unix-type platforms) provides control over the exception handling mechanism, in particular for applications that need to handle different types of exception in different ways.
** Similarly, classes [[ref:/libraries/base/reference/memory_chart|MEMORY]] and [[ref:/libraries/base/reference/gc_info_chart|GC_INFO]] provide ways to control the garbage collector and tailor it to specific needs.
** Class [[ref:libraries/base/reference/exceptions_chart|EXCEPTIONS]] (complemented by [[ref:libraries/base/reference/unix_signals_chart|UNIX_SIGNALS]] for Unix-type platforms) provides control over the exception handling mechanism, in particular for applications that need to handle different types of exception in different ways.
** Similarly, classes [[ref:libraries/base/reference/memory_chart|MEMORY]] and [[ref:libraries/base/reference/gc_info_chart|GC_INFO]] provide ways to control the garbage collector and tailor it to specific needs.
** Class ARGUMENTS gives access to the command-line arguments.
=Universal Class and its Features=
The Eiffel inheritance mechanism is set up in such a way that every class is a descendant of a Kernel Library class called [[ref:/libraries/base/reference/any_chart|ANY]] . The features of this class provide a number of generally applicable facilities covering such needs as comparison, copying and rudimentary input and output.
The Eiffel inheritance mechanism is set up in such a way that every class is a descendant of a Kernel Library class called [[ref:libraries/base/reference/any_chart|ANY]] . The features of this class provide a number of generally applicable facilities covering such needs as comparison, copying and rudimentary input and output.
==The structure of universal classes==
@@ -34,7 +34,7 @@ inherit
ANY
</code>
As a result, every developer-defined class is a descendant of [[ref:/libraries/base/reference/any_chart|ANY]] . You may introduce your own project specific features in [[ref:/libraries/base/reference/any_chart|ANY]] so that all the classes of your system will be able to use these features.
As a result, every developer-defined class is a descendant of [[ref:libraries/base/reference/any_chart|ANY]] . You may introduce your own project specific features in [[ref:libraries/base/reference/any_chart|ANY]] so that all the classes of your system will be able to use these features.
==Using the universal classes==
@@ -58,7 +58,7 @@ end
The features of [[ref:/libraries/base/reference/any_chart|ANY]] are usable in both qualified and unqualified form. For example, the argumentless function out, which produces a printable representation of any object, may be called under either of the forms
The features of [[ref:libraries/base/reference/any_chart|ANY]] are usable in both qualified and unqualified form. For example, the argumentless function out, which produces a printable representation of any object, may be called under either of the forms
<code>
x := out
x := a.out
@@ -68,9 +68,9 @@ The first call yields a printable representation of the current object; the seco
==Input and output features==
Some of the features of [[ref:/libraries/base/reference/any_chart|ANY]] cover common input and output needs. <br/>
Feature <eiffel>io</eiffel>, of type [[ref:/libraries/base/reference/std_files_chart|STD_FILES]] , gives access to standard input and output facilities. For example, <eiffel>io.input</eiffel> is the standard input file and <eiffel>io</eiffel>.<eiffel>new_line</eiffel> will print a line feed on the standard output. Feature <eiffel>io</eiffel> is declared as a once function which, when first called, returns the value of an instance of [[ref:/libraries/base/reference/std_files_chart|STD_FILES]] that provides access to the standard input, the standard output and the error output. As a result, <eiffel>io</eiffel> is never void, so that operations such as <eiffel>io</eiffel>.<eiffel>new_line</eiffel> are always possible. <br/>
Function <eiffel>out</eiffel>, of type [[ref:/libraries/base/reference/string_8_chart|STRING]] , is a universal mechanism for obtaining a simple external representation of any object. For non-void <code>x</code> of any type, the string <code>x.out</code> is a printable representation of <code>x</code>. This works for <code>x</code> of all types, reference or expanded. For example, if <code>x</code> is an integer expression, <code>x.out</code> is its string representation, such as <code>-897</code>; if n is a non-void reference, <code>x.out</code> is (recursively) the concatenation of the result of applying out to the successive fields of the attached object, each labeled by the name of the corresponding attribute. You may redefine out in any class to specify any suitable format for displaying instances of the class. To obtain the default representation regardless of any redefinition of out, use tagged_out, declared as a frozen synonym of the original out. <br/>
Some of the features of [[ref:libraries/base/reference/any_chart|ANY]] cover common input and output needs. <br/>
Feature <eiffel>io</eiffel>, of type [[ref:libraries/base/reference/std_files_chart|STD_FILES]] , gives access to standard input and output facilities. For example, <eiffel>io.input</eiffel> is the standard input file and <eiffel>io</eiffel>.<eiffel>new_line</eiffel> will print a line feed on the standard output. Feature <eiffel>io</eiffel> is declared as a once function which, when first called, returns the value of an instance of [[ref:libraries/base/reference/std_files_chart|STD_FILES]] that provides access to the standard input, the standard output and the error output. As a result, <eiffel>io</eiffel> is never void, so that operations such as <eiffel>io</eiffel>.<eiffel>new_line</eiffel> are always possible. <br/>
Function <eiffel>out</eiffel>, of type [[ref:libraries/base/reference/string_8_chart|STRING]] , is a universal mechanism for obtaining a simple external representation of any object. For non-void <code>x</code> of any type, the string <code>x.out</code> is a printable representation of <code>x</code>. This works for <code>x</code> of all types, reference or expanded. For example, if <code>x</code> is an integer expression, <code>x.out</code> is its string representation, such as <code>-897</code>; if n is a non-void reference, <code>x.out</code> is (recursively) the concatenation of the result of applying out to the successive fields of the attached object, each labeled by the name of the corresponding attribute. You may redefine out in any class to specify any suitable format for displaying instances of the class. To obtain the default representation regardless of any redefinition of out, use tagged_out, declared as a frozen synonym of the original out. <br/>
The call <code>print (x)</code> will output the value of <code>x.out</code> on the default output if <code>x</code> is not void, and do nothing otherwise.
==Copy and comparison routines==
@@ -88,7 +88,7 @@ starts by creating a new object, then populates its fields to be identical to <c
The boolean function <eiffel>equal</eiffel> compares two objects for field-by-field equality. This is different from the equality operators <code>=</code> and <code>/=</code> which, in the case of reference types, compare references, not objects. <br/>
The function <eiffel>deep_twin</eiffel> produces a duplicate of an entire object structure. The boolean function <eiffel>deep_equal</eiffel> determines whether two object structures are recursively identical. These routines are the ''deep'' counterparts of the shallow copy and equality tests provided by <eiffel>twin</eiffel> and <eiffel>equal</eiffel>. <br/>
A class that needs a specific notion of equality and the corresponding copy semantics may redefine <eiffel>copy</eiffel> and <eiffel>is_equal</eiffel> (from which <code>equal</code> follows, since <code>equal (a, b)</code> is defined as <code>a.is_equal (b)</code> for non-void <code>a</code>). You will find such redefinitions in a number of classes of the Base libraries. For example an instance of [[ref:/libraries/base/reference/string_8_chart|STRING]] is a string descriptor containing a reference to the actual character sequence, not that sequence itself, so that what the default equal compares and the default copy copies is the descriptor, not the string. Class [[ref:/libraries/base/reference/string_8_chart|STRING]] redefines these routines to yield the semantics normally expected by string clients; the frozen variants <eiffel>standard_copy</eiffel> and <eiffel>standard_equal</eiffel>, originally declared as synonyms to <eiffel>equal</eiffel> and <eiffel>copy</eiffel>, remain available with the default semantics. <br/>
A class that needs a specific notion of equality and the corresponding copy semantics may redefine <eiffel>copy</eiffel> and <eiffel>is_equal</eiffel> (from which <code>equal</code> follows, since <code>equal (a, b)</code> is defined as <code>a.is_equal (b)</code> for non-void <code>a</code>). You will find such redefinitions in a number of classes of the Base libraries. For example an instance of [[ref:libraries/base/reference/string_8_chart|STRING]] is a string descriptor containing a reference to the actual character sequence, not that sequence itself, so that what the default equal compares and the default copy copies is the descriptor, not the string. Class [[ref:libraries/base/reference/string_8_chart|STRING]] redefines these routines to yield the semantics normally expected by string clients; the frozen variants <eiffel>standard_copy</eiffel> and <eiffel>standard_equal</eiffel>, originally declared as synonyms to <eiffel>equal</eiffel> and <eiffel>copy</eiffel>, remain available with the default semantics. <br/>
The function <eiffel>twin</eiffel> is defined in terms of <eiffel>copy</eiffel>, and so will follow any redefinition of <eiffel>copy</eiffel>. This makes it impossible to change the semantics of one but not of the other, which would be a mistake. The variant <eiffel>standard_twin</eiffel> is defined in terms of <eiffel>standard_copy</eiffel>.
@@ -112,18 +112,18 @@ A number of classes offer facilities which are very close to the language level.
==Basic types==
The basic types [[ref:/libraries/base/reference/boolean_chart|BOOLEAN]] , [[ref:/libraries/base/reference/character_8_chart|CHARACTER]] , [[ref:/libraries/base/reference/integer_32_chart|INTEGER]] , [[ref:/libraries/base/reference/real_32_chart|REAL]] and [[ref:/libraries/base/reference/real_64_chart|DOUBLE]] are defined by classes of the Kernel library. <br/>
In reading the class specifications for the numeric types [[ref:/libraries/base/reference/integer_32_chart|INTEGER]] , [[ref:/libraries/base/reference/real_32_chart|REAL]] and [[ref:/libraries/base/reference/real_64_chart|DOUBLE]] , you might think that the type declarations are too restrictive. For example the addition operation in class [[ref:/libraries/base/reference/real_32_chart|REAL]] reads
The basic types [[ref:libraries/base/reference/boolean_chart|BOOLEAN]] , [[ref:libraries/base/reference/character_8_chart|CHARACTER]] , [[ref:libraries/base/reference/integer_32_chart|INTEGER]] , [[ref:libraries/base/reference/real_32_chart|REAL]] and [[ref:libraries/base/reference/real_64_chart|DOUBLE]] are defined by classes of the Kernel library. <br/>
In reading the class specifications for the numeric types [[ref:libraries/base/reference/integer_32_chart|INTEGER]] , [[ref:libraries/base/reference/real_32_chart|REAL]] and [[ref:libraries/base/reference/real_64_chart|DOUBLE]] , you might think that the type declarations are too restrictive. For example the addition operation in class [[ref:libraries/base/reference/real_32_chart|REAL]] reads
<code>
infix "+" (other: REAL): REAL
</code>
but there is actually no problem here. A language convention applicable to all arithmetic expressions, the Balancing rule, states that in any such expression all operands are considered to be converted to the heaviest type, where [[ref:/libraries/base/reference/real_64_chart|DOUBLE]] is heavier than [[ref:/libraries/base/reference/real_32_chart|REAL]] and [[ref:/libraries/base/reference/real_32_chart|REAL]] is heavier than [[ref:/libraries/base/reference/integer_32_chart|INTEGER]] . So mixed-type arithmetic, consistent with common practice, is possible and indeed frequent.
but there is actually no problem here. A language convention applicable to all arithmetic expressions, the Balancing rule, states that in any such expression all operands are considered to be converted to the heaviest type, where [[ref:libraries/base/reference/real_64_chart|DOUBLE]] is heavier than [[ref:libraries/base/reference/real_32_chart|REAL]] and [[ref:libraries/base/reference/real_32_chart|REAL]] is heavier than [[ref:libraries/base/reference/integer_32_chart|INTEGER]] . So mixed-type arithmetic, consistent with common practice, is possible and indeed frequent.
==Arrays==
To create and manipulate one-dimensional arrays, use class [[ref:/libraries/base/reference/array_chart|ARRAY]] of the Kernel Library. Arrays are not primitive language elements; instead, they are handled through class [[ref:/libraries/base/reference/array_chart|ARRAY]] . This class is 'normal' in the sense that it may be used just as any other class by client and descendant classes. It is also somewhat special, however, in that the Eiffel compiler knows about it and uses this knowledge to generate efficient code for array operations. <br/>
To create an instance of [[ref:/libraries/base/reference/array_chart|ARRAY]] , use the creation instruction
To create and manipulate one-dimensional arrays, use class [[ref:libraries/base/reference/array_chart|ARRAY]] of the Kernel Library. Arrays are not primitive language elements; instead, they are handled through class [[ref:libraries/base/reference/array_chart|ARRAY]] . This class is 'normal' in the sense that it may be used just as any other class by client and descendant classes. It is also somewhat special, however, in that the Eiffel compiler knows about it and uses this knowledge to generate efficient code for array operations. <br/>
To create an instance of [[ref:libraries/base/reference/array_chart|ARRAY]] , use the creation instruction
<code>
create my_array.make (1, u)
</code>
@@ -140,12 +140,12 @@ Function item has an infix synonym, <code>infix</code> <code>"</code>@ <code>"</
x := my_array @ i
</code>
<br/>
Features <eiffel>item</eiffel>, <code>infix</code> <code>"</code>@ <code>" </code>and <eiffel>put</eiffel> have preconditions requiring the index ( <code>i</code>in the above calls) to be within the bounds of the array. This means that you can detect bounds violations (which correspond to bugs in the client software) by using a version of class [[ref:/libraries/base/reference/array_chart|ARRAY]] compiled with precondition checking on. The bounds of an array may be changed dynamically through procedure <eiffel>resize</eiffel>. Previously entered elements are retained. Rather than an explicit resize, you may use calls to procedure <eiffel>force</eiffel> which has the same signature as put but no precondition; if the index is not within the current bounds force will perform a resize as necessary.
Features <eiffel>item</eiffel>, <code>infix</code> <code>"</code>@ <code>" </code>and <eiffel>put</eiffel> have preconditions requiring the index ( <code>i</code>in the above calls) to be within the bounds of the array. This means that you can detect bounds violations (which correspond to bugs in the client software) by using a version of class [[ref:libraries/base/reference/array_chart|ARRAY]] compiled with precondition checking on. The bounds of an array may be changed dynamically through procedure <eiffel>resize</eiffel>. Previously entered elements are retained. Rather than an explicit resize, you may use calls to procedure <eiffel>force</eiffel> which has the same signature as put but no precondition; if the index is not within the current bounds force will perform a resize as necessary.
==Optimizing array computations==
''' CAUTION''': Although [[ref:/libraries/base/reference/array_chart|ARRAY]] benefits from an efficient implementation, its more advanced facilities such as resizing do not come for free. For extensive computations on large arrays, an optimization may be desirable, bypassing these facilities. The technique yields loops that run at about the same speed as the corresponding loops written in C or Fortran (the usual references for array computations). It is of interest for advanced uses only, so that you may safely skip this section on first reading unless your domain of application is numerical computation or some other area requiring high-performance array manipulations.
''' CAUTION''': Although [[ref:libraries/base/reference/array_chart|ARRAY]] benefits from an efficient implementation, its more advanced facilities such as resizing do not come for free. For extensive computations on large arrays, an optimization may be desirable, bypassing these facilities. The technique yields loops that run at about the same speed as the corresponding loops written in C or Fortran (the usual references for array computations). It is of interest for advanced uses only, so that you may safely skip this section on first reading unless your domain of application is numerical computation or some other area requiring high-performance array manipulations.
The optimization relies on the class SPECIAL, used internally by [[ref:/libraries/base/reference/array_chart|ARRAY]] but of no direct interest to client developers in most common uses. With the declarations
The optimization relies on the class SPECIAL, used internally by [[ref:libraries/base/reference/array_chart|ARRAY]] but of no direct interest to client developers in most common uses. With the declarations
<code>
my_array: ARRAY [SOME_TYPE]
direct_access: SPECIAL [SOME_TYPE]
@@ -172,12 +172,12 @@ you may use <eiffel>direct_access</eiffel> in lieu of 'my_array' within a critic
end
</code>
This replaces an original loop where the operations were on <code>my_array</code>. Feature <eiffel>area</eiffel> of [[ref:/libraries/base/reference/array_chart|ARRAY]] gives direct access to the special object, an instance of SPECIAL, containing the array values. Features <eiffel>put</eiffel> and <eiffel>item</eiffel> are available in SPECIAL as in [[ref:/libraries/base/reference/array_chart|ARRAY]] , but without the preconditions; in other words, you will not get any bounds checking. Instances of SPECIAL are always indexed from zero, in contrast with arrays, whose lower bound is arbitrary, 1 being the most common value. But rather than performing index translations (that is to say, subtracting <code>my_array</code> <code>.</code><eiffel>lower</eiffel> from index throughout the loop) it is preferable to use the following simple technique: if the lower bound 'lb' of <code>my_array</code> is 1 or another small integer, use 0 as lower bound instead when creating <code>my_array</code>, but only use the positions starting at 'lb'. You will waste a few memory positions (0 to lb-1), but will not have to change anything in your algorithm and will avoid costly subtractions. <br/>
It is important to note that this optimization, if at all necessary, should at most affect a few loops in a large system. You should always begin by writing your software using the normal [[ref:/libraries/base/reference/array_chart|ARRAY]] facilities; then once you have the certainty that the software is correct, if you detect that a large array computation is hampering the efficiency of the system, you may apply the above technique to get the fastest performance out of that computation. The change to the software will be minimal - a few lines - and will be easy to undo if necessary.
This replaces an original loop where the operations were on <code>my_array</code>. Feature <eiffel>area</eiffel> of [[ref:libraries/base/reference/array_chart|ARRAY]] gives direct access to the special object, an instance of SPECIAL, containing the array values. Features <eiffel>put</eiffel> and <eiffel>item</eiffel> are available in SPECIAL as in [[ref:libraries/base/reference/array_chart|ARRAY]] , but without the preconditions; in other words, you will not get any bounds checking. Instances of SPECIAL are always indexed from zero, in contrast with arrays, whose lower bound is arbitrary, 1 being the most common value. But rather than performing index translations (that is to say, subtracting <code>my_array</code> <code>.</code><eiffel>lower</eiffel> from index throughout the loop) it is preferable to use the following simple technique: if the lower bound 'lb' of <code>my_array</code> is 1 or another small integer, use 0 as lower bound instead when creating <code>my_array</code>, but only use the positions starting at 'lb'. You will waste a few memory positions (0 to lb-1), but will not have to change anything in your algorithm and will avoid costly subtractions. <br/>
It is important to note that this optimization, if at all necessary, should at most affect a few loops in a large system. You should always begin by writing your software using the normal [[ref:libraries/base/reference/array_chart|ARRAY]] facilities; then once you have the certainty that the software is correct, if you detect that a large array computation is hampering the efficiency of the system, you may apply the above technique to get the fastest performance out of that computation. The change to the software will be minimal - a few lines - and will be easy to undo if necessary.
==Tuples==
A new Kernel Library class is introduced: [[ref:/libraries/base/reference/tuple_chart|TUPLE]] . <br/>
A new Kernel Library class is introduced: [[ref:libraries/base/reference/tuple_chart|TUPLE]] . <br/>
Alone among all classes, class TUPLE has a variable number of generic parameters. TUPLE, TUPLE [X], TUPLE [X, Y], TUPLE [X, Y, Z] and so on are all valid types, assuming valid types X, Y, Z and so on. <br/>
Conformance rules:
<code>[CONF1]
@@ -187,14 +187,14 @@ Conformance rules:
(and hence to TUPLE [T1, T2, ..., Tn] if each of the Ui conforms to each of the Ti for 1 <= i <= n.)
In particular all tuple types conform to [[ref:/libraries/base/reference/tuple_chart|TUPLE]] , with no parameter.
In particular all tuple types conform to [[ref:libraries/base/reference/tuple_chart|TUPLE]] , with no parameter.
<code>[CONF2]
For n >= 0 If *every* one of the types T1, T2, ..., Tn conforms
to a type T, then TUPLE [T1, T2, ..., Tn] conforms
to ARRAY [T]</code>
{{Definition|Tuple Type|A "tuple type" is any type based on class [[ref:/libraries/base/reference/tuple_chart|TUPLE]] , i.e. any type of the form <code>TUPLE [T1, T2, ..., Tn]</code> for any n (including 0, for which there is no generic parameter). }}
{{Definition|Tuple Type|A "tuple type" is any type based on class [[ref:libraries/base/reference/tuple_chart|TUPLE]] , i.e. any type of the form <code>TUPLE [T1, T2, ..., Tn]</code> for any n (including 0, for which there is no generic parameter). }}
{{note|CONF1 should be understood in terms of the underlying mathematical model. <br/>
@@ -204,7 +204,7 @@ With this definition, TUPLE <code>n</code> is indeed a subset of TUPLE <code>n+1
Semantics: an instance of TUPLE [T1, T2, ..., Tn] is a tuple whose first element is an instance of T1, the second element being an instance of T2 etc. (The precise definition is the mathematical one given in note 1.) Note that there can be more than n elements to the tuple: for example a tuple with first element 5 and second element "FOO" is an instance of all of the following tuple types: TUPLE; TUPLE [INTEGER]; TUPLE [INTEGER, STRING].
It may seem restrictive at first to permit only one class, [[ref:/libraries/base/reference/tuple_chart|TUPLE]] , to have an arbitrary number of actual generic parameters. Why not have a general mechanism for declaring any class C so that all of C [X], C [X, Y] etc. are valid? But in fact this is not really a restriction. To obtain this effect without any complicated language convention, just declare C as
It may seem restrictive at first to permit only one class, [[ref:libraries/base/reference/tuple_chart|TUPLE]] , to have an arbitrary number of actual generic parameters. Why not have a general mechanism for declaring any class C so that all of C [X], C [X, Y] etc. are valid? But in fact this is not really a restriction. To obtain this effect without any complicated language convention, just declare C as
C [G -> TUPLE]
and then use the generic derivations
@@ -236,11 +236,11 @@ As a special case of tuple expression syntax, the delimiters [ and ] are replace
==Tuple features==
The exact specification of class [[ref:/libraries/base/reference/tuple_chart|TUPLE]] will be described in an addition to ELKS. The principal features are:
* [[ref:/libraries/base/reference/tuple_chart|count]] (number of significant elements)
* [[ref:/libraries/base/reference/tuple_chart|item]] (i), with the obvious precondition: the i-th element, of type [[ref:/libraries/base/reference/any_chart|ANY]] (since the value of i is not known at compile time); also first, second, third, fourth and fifth, of the appropriate types.
* [[ref:/libraries/base/reference/tuple_chart|put]] (x, i), with the obvious precondition: replace i-th element with x. If argument x is not of the appropriate type T <code>i</code> there is no effect.
* [[ref:/libraries/base/reference/tuple_chart|is_equal]] : redefined to consider only the first n elements, where n is the smaller length.
The exact specification of class [[ref:libraries/base/reference/tuple_chart|TUPLE]] will be described in an addition to ELKS. The principal features are:
* [[ref:libraries/base/reference/tuple_chart|count]] (number of significant elements)
* [[ref:libraries/base/reference/tuple_chart|item]] (i), with the obvious precondition: the i-th element, of type [[ref:libraries/base/reference/any_chart|ANY]] (since the value of i is not known at compile time); also first, second, third, fourth and fifth, of the appropriate types.
* [[ref:libraries/base/reference/tuple_chart|put]] (x, i), with the obvious precondition: replace i-th element with x. If argument x is not of the appropriate type T <code>i</code> there is no effect.
* [[ref:libraries/base/reference/tuple_chart|is_equal]] : redefined to consider only the first n elements, where n is the smaller length.
Other features under consideration include:
* stripped (i): a tuple of type TUPLE [T1, T2, Ti-1, Ti+1, ..., Tn], derived from the current one by removing the i-th component, again with the obvious precondition.
@@ -276,12 +276,12 @@ For a set of important applications of tuples see the book chapter on [[EiffelBa
==Temporary limitations==
The implementation of tuples has the following limitations:
* Conformance of [[ref:/libraries/base/reference/array_chart|ARRAY]] types to [[ref:/libraries/base/reference/tuple_chart|TUPLE]] types is not yet fully supported.
* Class [[ref:/libraries/base/reference/tuple_chart|TUPLE]] does not have features such as first and second. You must use item and, in most cases, an object test.
* Conformance of [[ref:libraries/base/reference/array_chart|ARRAY]] types to [[ref:libraries/base/reference/tuple_chart|TUPLE]] types is not yet fully supported.
* Class [[ref:libraries/base/reference/tuple_chart|TUPLE]] does not have features such as first and second. You must use item and, in most cases, an object test.
==Strings==
Strings are handled by class [[ref:/libraries/base/reference/string_8_chart|STRING]] , similar in many respects to [[ref:/libraries/base/reference/array_chart|ARRAY]] . Strings are of arbitrary size. The make creation procedure takes an integer argument, as in:
Strings are handled by class [[ref:libraries/base/reference/string_8_chart|STRING]] , similar in many respects to [[ref:libraries/base/reference/array_chart|ARRAY]] . Strings are of arbitrary size. The make creation procedure takes an integer argument, as in:
<code>
s, s1, s2, s3: STRING
...
@@ -291,7 +291,7 @@ The argument indicates the number of characters for the initial allocation. This
==String descriptor==
The object attached at run-time to an entity such declared of type [[ref:/libraries/base/reference/string_8_chart|STRING]] is not the actual sequence of characters but a string descriptor, which contains a reference to the actual string contents.
The object attached at run-time to an entity such declared of type [[ref:libraries/base/reference/string_8_chart|STRING]] is not the actual sequence of characters but a string descriptor, which contains a reference to the actual string contents.
As a result, four assignment or assignment-like operations are possible:
* '''A1''' <code>s1 := s</code>
@@ -303,11 +303,11 @@ As illustrated below, ''' A1''' is a reference assignment: <code>s1</code> will
[[Image:strings]]
fig. 1: Effect of string assignment and copy operations
[[ref:/libraries/base/reference/basic_routines_chart|BASIC_ROUTINES]] provides a number of conversion functions, such as charconv.
[[ref:libraries/base/reference/basic_routines_chart|BASIC_ROUTINES]] provides a number of conversion functions, such as charconv.
=Files, Input, Output=
A few classes of the Kernel Library support file manipulation, input and output: [[ref:/libraries/base/reference/std_files_chart|STD_FILES]] , FILE, [[ref:/libraries/base/reference/directory_chart|DIRECTORY]] and [[ref:/libraries/base/reference/unix_file_info_chart|UNIX_FILE_INFO]] . For simple applications it suffices to use [[ref:/libraries/base/reference/std_files_chart|STD_FILES]] , but to understand the concepts better it is preferable to look first at the other two.
A few classes of the Kernel Library support file manipulation, input and output: [[ref:libraries/base/reference/std_files_chart|STD_FILES]] , FILE, [[ref:libraries/base/reference/directory_chart|DIRECTORY]] and [[ref:libraries/base/reference/unix_file_info_chart|UNIX_FILE_INFO]] . For simple applications it suffices to use [[ref:libraries/base/reference/std_files_chart|STD_FILES]] , but to understand the concepts better it is preferable to look first at the other two.
==General files==
@@ -327,33 +327,33 @@ Queries are available to determine the status of a file, in particular <eiffel>e
<code>if my_file.exists and then my_file.is_readable then</code>... }}
FILE is a deferred class. Various implementations are possible. A quite detailed one is PLAIN_TEXT_FILE, which adds many features for accessing reading and writing data from/to a file. <br/>
[[ref:/libraries/base/reference/unix_file_info_chart|UNIX_FILE_INFO]] describes objects that contain internal information, such as protection mode and size, about a file. <br/>
The class [[ref:/libraries/base/reference/directory_chart|DIRECTORY]] describes those files which are directories - nodes in the tree describing the file structure.
[[ref:libraries/base/reference/unix_file_info_chart|UNIX_FILE_INFO]] describes objects that contain internal information, such as protection mode and size, about a file. <br/>
The class [[ref:libraries/base/reference/directory_chart|DIRECTORY]] describes those files which are directories - nodes in the tree describing the file structure.
==Basic input and output==
Regardless of the operating system that you use, for simple input and output [[ref:/libraries/base/reference/std_files_chart|STD_FILES]] is sufficient. You may inherit from that class to gain direct access to its features; or you may declare an entity of type [[ref:/libraries/base/reference/std_files_chart|STD_FILES]] . But remember that a feature of this type is always available: io, from class [[ref:/libraries/base/reference/any_chart|ANY]] . Thanks to this feature you may include simple input and output in any class, with instructions such as
Regardless of the operating system that you use, for simple input and output [[ref:libraries/base/reference/std_files_chart|STD_FILES]] is sufficient. You may inherit from that class to gain direct access to its features; or you may declare an entity of type [[ref:libraries/base/reference/std_files_chart|STD_FILES]] . But remember that a feature of this type is always available: io, from class [[ref:libraries/base/reference/any_chart|ANY]] . Thanks to this feature you may include simple input and output in any class, with instructions such as
<code>io.put_string ("My message")</code>
[[ref:/libraries/base/reference/std_files_chart|STD_FILES]] defines three default files through features <eiffel>input</eiffel>, <eiffel>output</eiffel> and <eiffel>error</eiffel>. These features are Once functions, so that the first reference to any one of them will automatically create the corresponding file descriptor and open the associated file. <br/>
To simplify the writing of common input and output operations, the most frequently used features of class FILE - for reading and writing integers, reals and so on, as discussed next - have been repeated in [[ref:/libraries/base/reference/std_files_chart|STD_FILES]] so as to apply to the default input and output. Procedure put_string in the example at the beginning of this section is typical: it writes its output on the standard output. More generally, [[ref:/libraries/base/reference/std_files_chart|STD_FILES]] has all the <eiffel>put_xxx</eiffel>, <eiffel>read_xxx</eiffel> and <eiffel>last_xxx</eiffel> features of FILE.
[[ref:libraries/base/reference/std_files_chart|STD_FILES]] defines three default files through features <eiffel>input</eiffel>, <eiffel>output</eiffel> and <eiffel>error</eiffel>. These features are Once functions, so that the first reference to any one of them will automatically create the corresponding file descriptor and open the associated file. <br/>
To simplify the writing of common input and output operations, the most frequently used features of class FILE - for reading and writing integers, reals and so on, as discussed next - have been repeated in [[ref:libraries/base/reference/std_files_chart|STD_FILES]] so as to apply to the default input and output. Procedure put_string in the example at the beginning of this section is typical: it writes its output on the standard output. More generally, [[ref:libraries/base/reference/std_files_chart|STD_FILES]] has all the <eiffel>put_xxx</eiffel>, <eiffel>read_xxx</eiffel> and <eiffel>last_xxx</eiffel> features of FILE.
=PERSISTENCE, STORAGE AND RETRIEVAL=
=PERSISTENCE, STORAGE, AND RETRIEVAL=
Most object-oriented applications need the ability to store object structures on persistent storage for later retrieval, and to transfer such object structures to other applications. <br/>
Class [[ref:/libraries/base/reference/storable_chart|STORABLE]] addresses this need.
Class [[ref:libraries/base/reference/storable_chart|STORABLE]] addresses this need.
==Persistence completeness==
A fundamental requirement on object persistence mechanisms is the '' Persistence Completeness'' rule, stated as follows in ''[[Eiffel: The Language]]'': <br/>
Whenever a routine of class [[ref:/libraries/base/reference/storable_chart|STORABLE]] stores an object into an external file, it stores with it the dependents of that object. Whenever one of the associated retrieval routines retrieves a previously stored object, it also retrieves all its dependents. <br/>
Storing an object just by itself would usually result in wrong semantics: most objects contain references to other objects, which must also be stored and retrieved with it. The persistence completeness rule ensures that this is always the case. It also means, of course, that the features of [[ref:/libraries/base/reference/storable_chart|STORABLE]] must do much more than simple input and output; they must perform complete traversals of object structures.
Whenever a routine of class [[ref:libraries/base/reference/storable_chart|STORABLE]] stores an object into an external file, it stores with it the dependents of that object. Whenever one of the associated retrieval routines retrieves a previously stored object, it also retrieves all its dependents. <br/>
Storing an object just by itself would usually result in wrong semantics: most objects contain references to other objects, which must also be stored and retrieved with it. The persistence completeness rule ensures that this is always the case. It also means, of course, that the features of [[ref:libraries/base/reference/storable_chart|STORABLE]] must do much more than simple input and output; they must perform complete traversals of object structures.
==Using the storage and retrieval facilities==
Class [[ref:/libraries/base/reference/storable_chart|STORABLE]] is meant to be used as ancestor. You can use its features in any descendant <eiffel>C</eiffel>; for example a routine of <eiffel>C</eiffel> may contain a call of the form <eiffel>basic_store</eiffel> <code>(</code> <code>my_descriptor</code> <code>)</code>. <br/>
Class [[ref:libraries/base/reference/storable_chart|STORABLE]] is meant to be used as ancestor. You can use its features in any descendant <eiffel>C</eiffel>; for example a routine of <eiffel>C</eiffel> may contain a call of the form <eiffel>basic_store</eiffel> <code>(</code> <code>my_descriptor</code> <code>)</code>. <br/>
The effect of this call will be to store the current object and all its dependents into the file denoted by my_descriptor. <br/>
Although basic_store and other procedures of [[ref:/libraries/base/reference/storable_chart|STORABLE]] will in general process objects of many different types, only the generating class of the structure's initial object, <eiffel>C</eiffel> in our example, needs to be a descendant of [[ref:/libraries/base/reference/storable_chart|STORABLE]] .
Although basic_store and other procedures of [[ref:libraries/base/reference/storable_chart|STORABLE]] will in general process objects of many different types, only the generating class of the structure's initial object, <eiffel>C</eiffel> in our example, needs to be a descendant of [[ref:libraries/base/reference/storable_chart|STORABLE]] .
==Varieties of store operations==
@@ -363,7 +363,7 @@ subsequent execution of the same system. If you need to store objects from a cer
==Retrieval==
You only need to be aware of the difference between basic and general store at storage time. The stored structure will always be available through feature retrieved; this feature will figure out, from the format of the stored structure, whether it was stored by <eiffel>basic_store</eiffel>, <eiffel>general_store</eiffel>, or <eiffel>independent_store</eiffel> and will decode it accordingly. <br/>
Feature <eiffel>retrieved</eiffel> returns a result of type [[ref:/libraries/base/reference/any_chart|ANY]] and is typically used through an object test of the form
Feature <eiffel>retrieved</eiffel> returns a result of type [[ref:libraries/base/reference/any_chart|ANY]] and is typically used through an object test of the form
<code>
if attached {SOME_EXPECTED_TYPE} retrieved (my_descriptor) as l_temp then
-- Retrieved result is of expected type
@@ -374,17 +374,17 @@ Feature <eiffel>retrieved</eiffel> returns a result of type [[ref:/libraries/bas
</code>
<br/>
The object test is necessary because <eiffel>retrieved</eiffel> returns a result of type [[ref:/libraries/base/reference/any_chart|ANY]] whereas the type of <code>x</code> will be based on a proper descendant of [[ref:/libraries/base/reference/any_chart|ANY]] . If the structure in the file has been corrupted and <eiffel>retrieved</eiffel> is unable to do its job, it will trigger an exception. The code for that exception in class [[ref:/libraries/base/reference/exceptions_chart|EXCEPTIONS]] (which inherits it from EXCEP_CONST and is discussed in the next section, together with the notion of exception code) is <eiffel>Retrieve_exception</eiffel>.
The object test is necessary because <eiffel>retrieved</eiffel> returns a result of type [[ref:libraries/base/reference/any_chart|ANY]] whereas the type of <code>x</code> will be based on a proper descendant of [[ref:libraries/base/reference/any_chart|ANY]] . If the structure in the file has been corrupted and <eiffel>retrieved</eiffel> is unable to do its job, it will trigger an exception. The code for that exception in class [[ref:libraries/base/reference/exceptions_chart|EXCEPTIONS]] (which inherits it from EXCEP_CONST and is discussed in the next section, together with the notion of exception code) is <eiffel>Retrieve_exception</eiffel>.
==Recoverable storable==
Sometime you will be in a position where the schema of a class will have changed between the time you stored your object and the time you are trying to retrieve it. Such changes include:
Sometimes you will be in a position where the schema of a class will have changed between the time you stored your object and the time you are trying to retrieve it. Such changes include:
* class name changed
* attributes have been added or removed
* attributes have been renamed
* attributes type have changed
The storable mechanism allows you to retrieve the old version of the object only if it was saved using the <eiffel>independent_store</eiffel> facility. Each time you retrieve an object of a certain base class whose schema has changed, the feature <eiffel>correct_mismatch</eiffel> will be called. This feature is defined in [[ref:/libraries/base/reference/any_chart|ANY]] and by default will raise an exception. To handle the mismatch, you need to redefine <eiffel>correct_mismatch</eiffel> in the base class whose schema has been changed. For example in EiffelBase, [[ref:/libraries/base/reference/hash_table_chart|HASH_TABLE]] has changed between version 5.1 and version 5.2 to use <eiffel> SPECIAL</eiffel> rather than [[ref:/libraries/base/reference/array_chart|ARRAY]] for its internal data storage. To retrieve a 5.1 version of [[ref:/libraries/base/reference/hash_table_chart|HASH_TABLE]], you need to define <eiffel>correct_mismatch</eiffel> as following:
The storable mechanism allows you to retrieve the old version of the object only if it was saved using the <eiffel>independent_store</eiffel> facility. Each time you retrieve an object of a certain base class whose schema has changed, the feature <eiffel>correct_mismatch</eiffel> will be called. This feature is defined in [[ref:libraries/base/reference/any_chart|ANY]] and by default will raise an exception. To handle the mismatch, you need to redefine <eiffel>correct_mismatch</eiffel> in the base class whose schema has been changed. For example in EiffelBase, [[ref:libraries/base/reference/hash_table_chart|HASH_TABLE]] has changed between version 5.1 and version 5.2 to use <eiffel> SPECIAL</eiffel> rather than [[ref:libraries/base/reference/array_chart|ARRAY]] for its internal data storage. To retrieve a 5.1 version of [[ref:libraries/base/reference/hash_table_chart|HASH_TABLE]], you need to define <eiffel>correct_mismatch</eiffel> as following:
<code>
correct_mismatch
-- Attempt to correct object mismatch during retrieve using `mismatch_information'.
@@ -416,57 +416,57 @@ correct_mismatch
end
</code>
Note the use of <eiffel>mismatch_information</eiffel>, this is a once feature of [[ref:/libraries/base/reference/any_chart|ANY]] of type <eiffel>MISMATCH_INFORMATION</eiffel> which behaves like a [[ref:/libraries/base/reference/hash_table_chart|HASH_TABLE]]. The keys of the table are the names of the attributes on which a mismatch occurred and the values are the corresponding object fields as they were originally stored. In this particular case of [[ref:/libraries/base/reference/hash_table_chart|HASH_TABLE]] we know that the previous version was an [[ref:/libraries/base/reference/array_chart|ARRAY]], so we do an object test and if it succeeds we assign its <eiffel>area</eiffel> to the corresponding attribute of [[ref:/libraries/base/reference/hash_table_chart|HASH_TABLE]].
Note the use of <eiffel>mismatch_information</eiffel>, this is a once feature of [[ref:libraries/base/reference/any_chart|ANY]] of type <eiffel>MISMATCH_INFORMATION</eiffel> which behaves like a [[ref:libraries/base/reference/hash_table_chart|HASH_TABLE]]. The keys of the table are the names of the attributes on which a mismatch occurred and the values are the corresponding object fields as they were originally stored. In this particular case of [[ref:libraries/base/reference/hash_table_chart|HASH_TABLE]] we know that the previous version was an [[ref:libraries/base/reference/array_chart|ARRAY]], so we do an object test and if it succeeds we assign its <eiffel>area</eiffel> to the corresponding attribute of [[ref:libraries/base/reference/hash_table_chart|HASH_TABLE]].
If a class name changed, then you need to create an instance of <eiffel>CLASS_NAME_TRANSLATIONS</eiffel>, it behaves like a [[ref:/libraries/base/reference/hash_table_chart|HASH_TABLE]] where the keys represent the old name, and the value the new name. This instance needs to be created before the call to retrieved.
If a class name changed, then you need to create an instance of <eiffel>CLASS_NAME_TRANSLATIONS</eiffel>, it behaves like a [[ref:libraries/base/reference/hash_table_chart|HASH_TABLE]] where the keys represent the old name, and the value the new name. This instance needs to be created before the call to retrieved.
=Access To Internal Properties=
In some applications you may need to fine-tune the exception handling and memory management mechanisms. You may also need a simple way to access command-line arguments. In less common cases you may require low-level access to internal properties of objects.
In some applications, you may need to fine-tune the exception handling and memory management mechanisms. You may also need a simple way to access command-line arguments. In less common cases, you may require low-level access to internal properties of objects.
==Exception handling==
Class [[ref:/libraries/base/reference/exceptions_chart|EXCEPTIONS]] enables you to control the handling of exceptions. [[ref:/libraries/base/reference/unix_signals_chart|UNIX_SIGNALS]] , discussed next, complements it for the special case of fine-grain signal handling on Unix or Unix-like platforms. Both are meant to be inherited by any class that needs their facilities. <br/>
The basic exception mechanism treats all exceptions in the same way. In some cases it may be useful to discriminate in a Rescue clause between the various possible causes. <br/>
Class [[ref:/libraries/base/reference/exceptions_chart|EXCEPTIONS]] provides the features to do this. Each kind of exception has an integer code, which you can use through several features:
Class [[ref:libraries/base/reference/exceptions_chart|EXCEPTIONS]] enables you to control the handling of exceptions. [[ref:libraries/base/reference/unix_signals_chart|UNIX_SIGNALS]] , discussed next, complements it for the special case of fine-grain signal handling on Unix or Unix-like platforms. Both are meant to be inherited by any class that needs their facilities. <br/>
The basic exception mechanism treats all exceptions in the same way. In some cases, it may be useful to discriminate in a Rescue clause between the various possible causes. <br/>
Class [[ref:libraries/base/reference/exceptions_chart|EXCEPTIONS]] provides the features to do this. Each kind of exception has an integer code, which you can use through several features:
* The integer-valued query exception which gives the code of the latest exception.
* Queries which determine the general nature of the latest exception: <eiffel>is_signal</eiffel> which determines whether the exception was an operating system signal; <eiffel>is_developer_exception</eiffel> which determines whether it was explicitly caused by a raise, as explained next; <eiffel>assertion_violation</eiffel>.
* Query<eiffel> recipient_name</eiffel> which gives the name of the exception's recipient - the routine that was interrupted by the exception.
The class also provides a set of constant integer-valued attributes which denote the various possible codes, such as <eiffel>No_more_memory</eiffel>, <eiffel>Routine_ failure</eiffel> and <eiffel>Precondition_violation</eiffel>. So you can test the value of exception against these codes if you need to ascertain the precise nature of an exception. To keep [[ref:/libraries/base/reference/exceptions_chart|EXCEPTIONS]] simple these constant attributes are declared in a class EXCEP_CONST, of which [[ref:/libraries/base/reference/exceptions_chart|EXCEPTIONS]] is an heir. <br/>
The class also provides a set of constant integer-valued attributes which denote the various possible codes, such as <eiffel>No_more_memory</eiffel>, <eiffel>Routine_ failure</eiffel> and <eiffel>Precondition_violation</eiffel>. So you can test the value of exception against these codes if you need to ascertain the precise nature of an exception. To keep [[ref:libraries/base/reference/exceptions_chart|EXCEPTIONS]] simple these constant attributes are declared in a class EXCEP_CONST, of which [[ref:libraries/base/reference/exceptions_chart|EXCEPTIONS]] is an heir. <br/>
Another occasional requirement is for a mechanism to trigger an exception explicitly. Procedure raise answers this needs; the argument, a string, is the tag chosen for the exception. The code in this case is <eiffel>Developer_exception</eiffel>; the query <eiffel>is_developer_exception</eiffel> will return true; and the tag is accessible through feature <eiffel>tag_name</eiffel>. <br/>
You will notice in the interface specification for [[ref:/libraries/base/reference/exceptions_chart|EXCEPTIONS]] that for some properties of the latest exception there are two features, one with a name such as exception or recipient_name as seen above and the other with a name prefixed by original_: <eiffel>original_exception</eiffel>, <eiffel>original_recipient_name</eiffel>.
You will notice in the interface specification for [[ref:libraries/base/reference/exceptions_chart|EXCEPTIONS]] that for some properties of the latest exception there are two features, one with a name such as exception or recipient_name as seen above and the other with a name prefixed by original_: <eiffel>original_exception</eiffel>, <eiffel>original_recipient_name</eiffel>.
{{caution|The reason for the presence of these pairs is that the immediately visible cause of a routine interruption may not be the real one. Assume that routine <eiffel>r</eiffel> from class <eiffel>C</eiffel>, which has a Rescue clause, calls <eiffel>s</eiffel> from <eiffel>D</eiffel> with no Rescue clause, and that some call executed by <eiffel>s</eiffel> causes a precondition violation. Because <eiffel>s</eiffel> has no Rescue clause of its own, <eiffel>s</eiffel> will fail. Up the call chain, the first routine that has a Rescue clause - <eiffel>r</eiffel> itself, or one of its own direct or indirect callers - may process the exception; but if it examines the exception code through attribute exception it will get the value of <eiffel>Routine_failure</eiffel>. This may be what you want; but to handle the situation in a finer way you will usually need to examine the code for the original exception, the one that interrupted <eiffel>s</eiffel>. This code will be accessible through the attribute original_exception, which in this case will have the value of <eiffel>Precondition</eiffel>, the exception code for precondition violations. So you have the choice between exploring the properties of the original exception, or those of the resulting routine failures. Just make sure you know what you are looking for. }}
As you will see from the header comments in the flat-short form of class [[ref:/libraries/base/reference/exceptions_chart|EXCEPTIONS]] , the queries that return detailed information about an exception, such as <eiffel>assertion_violation</eiffel>, all give an answer determined by <eiffel>original_exception</eiffel> rather than <eiffel>exception</eiffel>, since when the two are different (that is to say, when you handle the exception in a routine other than the original recipient) the value of exception is always <eiffel>Routine_failure</eiffel> and there is nothing more to say about it.
As you will see from the header comments in the flat-short form of class [[ref:libraries/base/reference/exceptions_chart|EXCEPTIONS]] , the queries that return detailed information about an exception, such as <eiffel>assertion_violation</eiffel>, all give an answer determined by <eiffel>original_exception</eiffel> rather than <eiffel>exception</eiffel>, since when the two are different (that is to say, when you handle the exception in a routine other than the original recipient) the value of exception is always <eiffel>Routine_failure</eiffel> and there is nothing more to say about it.
==Signal handling==
The features of class [[ref:/libraries/base/reference/exceptions_chart|EXCEPTIONS]] enable you to determine whether a certain exception is a signal - an operating system event such as may result from a child process that disappears, a window that is resized, a user that hits the Break key and many others. But they do not give you more details because the exact set of possible signals is highly platform-dependent. <br/>
Class [[ref:/libraries/base/reference/unix_signals_chart|UNIX_SIGNALS]] complements EXCEP_CONST by providing codes for the signals of Unix and similar systems, such as Sigkill for the 'kill' signal and Sigbus for bus error. <br/>
The features of class [[ref:libraries/base/reference/exceptions_chart|EXCEPTIONS]] enable you to determine whether a certain exception is a signal - an operating system event such as may result from a child process that disappears, a window that is resized, a user that hits the Break key and many others. But they do not give you more details because the exact set of possible signals is highly platform-dependent. <br/>
Class [[ref:libraries/base/reference/unix_signals_chart|UNIX_SIGNALS]] complements EXCEP_CONST by providing codes for the signals of Unix and similar systems, such as Sigkill for the 'kill' signal and Sigbus for bus error. <br/>
Query <eiffel>is_defined </eiffel> <code>(some_signal)</code>, where <code>some_signal</code> is an integer code, will determine whether some_signal is supported on the platform. <br/>
A class whose routines need to perform specific processing depending on the nature of signals received should inherit from [[ref:/libraries/base/reference/unix_signals_chart|UNIX_SIGNALS]] , or a similar class for another platform. <br/>
Because signal codes are platform-dependent, the features of [[ref:/libraries/base/reference/unix_signals_chart|UNIX_SIGNALS]] are implemented as once functions - computed on the first call - rather than constants, although this makes no difference to clients.
A class whose routines need to perform specific processing depending on the nature of signals received should inherit from [[ref:libraries/base/reference/unix_signals_chart|UNIX_SIGNALS]] , or a similar class for another platform. <br/>
Because signal codes are platform-dependent, the features of [[ref:libraries/base/reference/unix_signals_chart|UNIX_SIGNALS]] are implemented as once functions - computed on the first call - rather than constants, although this makes no difference to clients.
==Memory management==
Class [[ref:/libraries/base/reference/memory_chart|MEMORY]] , like [[ref:/libraries/base/reference/exceptions_chart|EXCEPTIONS]] , is meant to be used as an ancestor by classes that need its facilities. It offers a number of features for controlling memory management and fine-tuning the garbage collection mechanism, a key component of the Eiffel Software environment. <br/>
One of the most useful features in this class is dispose. This procedure describes actions to be applied to an unreachable object just before the garbage collector reclaims it. By default, as declared in [[ref:/libraries/base/reference/memory_chart|MEMORY]] , the procedure does nothing; but you may redefine it in a proper descendant of [[ref:/libraries/base/reference/memory_chart|MEMORY]] to describe dispose actions. Normally such actions will involve freeing external resources: for example a class describing file descriptors may redefine dispose so that whenever a descriptor object is garbage-collected the corresponding file will be closed.
Class [[ref:libraries/base/reference/memory_chart|MEMORY]] , like [[ref:libraries/base/reference/exceptions_chart|EXCEPTIONS]] , is meant to be used as an ancestor by classes that need its facilities. It offers a number of features for controlling memory management and fine-tuning the garbage collection mechanism, a key component of the Eiffel Software environment. <br/>
One of the most useful features in this class is <e>dispose</e>. This procedure describes actions to be applied to an unreachable object just before the garbage collector reclaims it. By default, as declared in [[ref:libraries/base/reference/memory_chart|MEMORY]] , the procedure does nothing; but you may redefine it in a proper descendant of [[ref:libraries/base/reference/memory_chart|MEMORY]] to describe dispose actions. Normally such actions will involve freeing external resources: for example a class describing file descriptors may redefine <e>dispose</e> so that whenever a descriptor object is garbage-collected the corresponding file will be closed.
{{caution|This example is typical of proper uses of dispose. In a dispose procedure you should not include any instruction that could modify the Eiffel object structure, especially if some objects in that structure may themselves have become unreachable: these instructions could conflict with the garbage collector's operations and cause catastrophic behavior. The legitimate use of dispose redefinitions is for disposing of non-Eiffel resources. }}
{{caution|This example is typical of proper uses of <e>dispose</e>. In a dispose <e>procedure</e>, you should not include any instruction that could modify the Eiffel object structure, especially if some objects in that structure may themselves have become unreachable: these instructions could conflict with the garbage collector's operations and cause catastrophic behavior. The legitimate use of <e>dispose</e> redefinition is for disposing of non-Eiffel resources. }}
Other features of [[ref:/libraries/base/reference/memory_chart|MEMORY]] provide direct control over the operation of the garbage collector. You can in particular stop garbage collection through a call to <eiffel>collection_off</eiffel>, and restart it through a call to <eiffel>collection_on</eiffel>. By default, garbage collection is always on (a testimony to its authors' trust in its efficiency). Garbage collection is normally incremental, so as not to disrupt the application in a perceptible way. To start a complete garbage collection mechanism - reclaiming all unused objects - call procedure <eiffel>full_collect</eiffel>. The remaining features of [[ref:/libraries/base/reference/memory_chart|MEMORY]] enable finer control of the collection mechanism and are useful in special cases only. You will even find a free procedure providing brave (and competent) developers with a mechanism for reclaiming individual objects manually. <br/>
MEM_INFO, the result type for query <eiffel>memory_statistics</eiffel> in [[ref:/libraries/base/reference/memory_chart|MEMORY]] , describes objects containing information collected about memory usage. The features of [[ref:/libraries/base/reference/gc_info_chart|GC_INFO]] provide statistics about the garbage collector's operation.
Other features of [[ref:libraries/base/reference/memory_chart|MEMORY]] provide direct control over the operation of the garbage collector. You can in particular stop garbage collection through a call to <eiffel>collection_off</eiffel>, and restart it through a call to <eiffel>collection_on</eiffel>. By default, garbage collection is always on (a testimony to its authors' trust in its efficiency). Garbage collection is normally incremental, so as not to disrupt the application in a perceptible way. To start a complete garbage collection mechanism - reclaiming all unused objects - call procedure <eiffel>full_collect</eiffel>. The remaining features of [[ref:libraries/base/reference/memory_chart|MEMORY]] enable finer control of the collection mechanism and are useful in special cases only. You will even find a free procedure providing brave (and competent) developers with a mechanism for reclaiming individual objects manually. <br/>
MEM_INFO, the result type for query <eiffel>memory_statistics</eiffel> in [[ref:libraries/base/reference/memory_chart|MEMORY]] , describes objects containing information collected about memory usage. The features of [[ref:libraries/base/reference/gc_info_chart|GC_INFO]] provide statistics about the garbage collector's operation.
==Command-line arguments==
Writing, assembling and compiling a system yields an executable command. The system's users will call that command with arguments. These are normally provided in textual form on the command line, as in
<code>your_system arg1 arg2 arg3</code>
although one may conceive of other ways of entering the command arguments, such as tabular or graphical form-filling. In any case the software must be able to access the values passed as command arguments. <br/>
although one may conceive of other ways of entering the command arguments, such as tabular or graphical form-filling. In any case, the software must be able to access the values passed as command arguments. <br/>
A language mechanism is available for that purpose: the Root Class rule indicates that the creation procedure of the root class may have a single argument (in the Eiffel sense of argument to a routine) of type <code>ARRAY[STRING]</code>. The corresponding array of strings will be initialized at the beginning of the system's execution with the values entered as arguments to that execution of the command. <br/>
Although this facility suffices in many cases, it is not always convenient if you suddenly need to access the command arguments in a class that is far-away from the root. An alternative mechanism, class ARGUMENTS, is available. Once again, this is a class from which you should inherit if you need its facilities. It has just two exported features:
Although this facility suffices in many cases, it is not always convenient if you suddenly need to access the command arguments in a class that is far away from the root. An alternative mechanism, class ARGUMENTS, is available. Once again, this is a class from which you should inherit if you need its facilities. It has just two exported features:
* <eiffel>argument_count</eiffel>, a non-negative integer, is the number of command arguments.
* <eiffel>argument</eiffel> <code>(</code>i<code>)</code>, a string, is the i-th command argument. Here <code>i</code> must be between 0 and <eiffel>argument_count</eiffel>; the convention is that for <code>i </code> <code>= 0</code> the result is the name of the command itself.