mirror of
https://github.com/EiffelSoftware/eiffel-org.git
synced 2025-12-08 15:52:26 +01:00
Author:halw
Date:2008-09-29T02:03:12.000000Z git-svn-id: https://svn.eiffel.com/eiffel-org/trunk@60 abb3cda0-5349-4a8f-a601-0c33ac3a8c38
This commit is contained in:
@@ -285,7 +285,7 @@ The classes describing list cells are descendants of a deferred class called [[r
|
||||
Class [[ref:/libraries/base/reference/linkable_chart|LINKABLE]] is an effective descendant of [[ref:/libraries/base/reference/cell_chart|CELL]] , used for one-way linked structures. It introduces features <eiffel>right</eiffel>, a reference to another cell to which the current <br/>
|
||||
cell will be linked. Two-way linked structures use [[ref:/libraries/base/reference/bi_linkable_chart|BI_LINKABLE]] , an heir of [[ref:/libraries/base/reference/linkable_chart|LINKABLE]] which to the above features adds <eiffel>left</eiffel>, a reference to the preceding cell in the structure.
|
||||
|
||||
{{warning| '''Caution''': Do not confuse the <eiffel>item</eiffel> feature of [[ref:/libraries/base/reference/cell_chart|CELL]] and its descendants, such as [[ref:/libraries/base/reference/linkable_chart|LINKABLE]] , with the <eiffel>item</eiffel> feature of the classes describing linear structures, such as [[ref:/libraries/base/reference/linked_list_chart|LINKED_LIST]] . For a linked list, <eiffel>item</eiffel> returns the item at cursor position. }}
|
||||
{{caution|Do not confuse the <eiffel>item</eiffel> feature of [[ref:/libraries/base/reference/cell_chart|CELL]] and its descendants, such as [[ref:/libraries/base/reference/linkable_chart|LINKABLE]] , with the <eiffel>item</eiffel> feature of the classes describing linear structures, such as [[ref:/libraries/base/reference/linked_list_chart|LINKED_LIST]] . For a linked list, <eiffel>item</eiffel> returns the item at cursor position. }}
|
||||
|
||||
It may be implemented as
|
||||
<code>item: G is
|
||||
@@ -301,7 +301,7 @@ using the <eiffel>item</eiffel> feature of [[ref:/libraries/base/reference/linka
|
||||
If you look at the interfaces of one-way and two-way linked structures, you will notice that they are almost identical. This is because it is possible to implement features such as <eiffel>back</eiffel> for one-way structures such as described by [[ref:/libraries/base/reference/linked_list_chart|LINKED_LIST]] and [[ref:/libraries/base/reference/linked_circular_chart|LINKED_CIRCULAR]] . A simple implementation of <eiffel>back</eiffel> stores away a reference to the current active item, executes <eiffel>start</eiffel>, and then performs <eiffel>forth</eiffel> until the item to the right of the cursor position is the previous <eiffel>active</eiffel>. <br/>
|
||||
Although correct, such an implementation is of course rather inefficient since it requires a traversal of the list. In terms of algorithmic complexity, it is in O (<eiffel>count</eiffel>), meaning that its execution time is on the average proportional to the number of items in the structure. In contrast, <eiffel>forth</eiffel> is O (1), that is to say, takes an execution time bounded by a constant.
|
||||
|
||||
{{warning| '''Caution''': As a consequence, you should not use one-way linked structures if you need to execute more than occasional <eiffel>back</eiffel> operations (and other operations requiring access to previous items, such as <eiffel>remove_left</eiffel>). }}
|
||||
{{caution|As a consequence, you should not use one-way linked structures if you need to execute more than occasional <eiffel>back</eiffel> operations (and other operations requiring access to previous items, such as <eiffel>remove_left</eiffel>). }}
|
||||
|
||||
Two-way linked structures, such as those described by [[ref:/libraries/base/reference/two_way_list_chart|TWO_WAY_LIST]] and [[ref:/libraries/base/reference/two_way_circular_chart|TWO_WAY_CIRCULAR]] , treat the two directions symmetrically, so that <eiffel>back</eiffel> will be just as efficient as <eiffel>forth</eiffel>. Hence the following important advice: If you need to traverse a linked structure both ways, not just left to right, use the <eiffel>TWO_WAY_</eiffel> classes, not the <eiffel>LINKED_</eiffel> versions. The <eiffel>TWO_WAY_</eiffel> structures will take up more space, since they use [[ref:/libraries/base/reference/bi_linkable_chart|BI_LINKABLE]] rather than [[ref:/libraries/base/reference/linkable_chart|LINKABLE]] cells, but for most applications this space penalty is justified by the considerable gains in time that will result if right-to-left operations are frequently needed.
|
||||
|
||||
@@ -315,7 +315,7 @@ An instance of [[ref:/libraries/base/reference/fixed_list_chart|FIXED_LIST]] , a
|
||||
|
||||
In contrast, [[ref:/libraries/base/reference/arrayed_list_chart|ARRAYED_LIST]] has almost the same interface as [[ref:/libraries/base/reference/linked_list_chart|LINKED_LIST]] . In particular, it is possible to add items at the end using procedure <eiffel>extend</eiffel>; if the call causes the list to grow beyond the current array's capacity, it will trigger a resizing. This is achieved by using the procedure <eiffel>force</eiffel> of class ARRAY to implement <eiffel>extend</eiffel>. [[ref:/libraries/base/reference/arrayed_list_chart|ARRAYED_LIST]] even has the insertion procedures (<eiffel>put_front</eiffel>, <eiffel>put_left</eiffel>, <eiffel>put_right</eiffel>) and removal procedures (<eiffel>prune</eiffel>, <eiffel>remove</eiffel>, <eiffel>remove_left</eiffel>, <eiffel>remove_right</eiffel>) that apply to arbitrary positions and appear in the linked implementations. These procedures, however, are rather inefficient, since they usually require moving a whole set of array items, an O (count) operation. (Procedure <eiffel>extend</eiffel> does not suffer from this problem, since it is easy to add an item to the end of an array, especially if there is still room so that no resizing is necessary.)
|
||||
|
||||
{{warning| '''Caution''': The situation of these features in [[ref:/libraries/base/reference/arrayed_list_chart|ARRAYED_LIST]] is similar to the situation of <eiffel>back</eiffel> in classes describing one-way linked structures: it is convenient to include them because they may be needed once in a while and an implementation exists; but using them more than occasionally may result in serious inefficiencies. If you do need to perform arbitrary insertions and removal, use linked structures, not arrayed ones. }}
|
||||
{{caution|The situation of these features in [[ref:/libraries/base/reference/arrayed_list_chart|ARRAYED_LIST]] is similar to the situation of <eiffel>back</eiffel> in classes describing one-way linked structures: it is convenient to include them because they may be needed once in a while and an implementation exists; but using them more than occasionally may result in serious inefficiencies. If you do need to perform arbitrary insertions and removal, use linked structures, not arrayed ones. }}
|
||||
|
||||
Arrayed structures, however, use up less space than linked representations. So they are appropriate for chains on which, except possibly for insertions at the end, few insertion and removal operations or none at all are expected after creation. [[ref:/libraries/base/reference/fixed_list_chart|FIXED_LIST]] offers few advantages over [[ref:/libraries/base/reference/arrayed_list_chart|ARRAYED_LIST]] . [[ref:/libraries/base/reference/fixed_list_chart|FIXED_LIST]] may be useful, however, for cases in which the fixed number of items is part of the specification, and any attempt to add more items must be treated as an error. For circular chains only one variant is available, [[ref:/libraries/base/reference/arrayed_circular_chart|ARRAYED_CIRCULAR]] , although writing a <eiffel>FIXED_</eiffel> version would be a simple exercise.
|
||||
|
||||
@@ -336,7 +336,7 @@ The class [[ref:/libraries/base/reference/comparable_struct_chart|COMPARABLE_STR
|
||||
|
||||
As indicated by the constrained generic parameter it describes bilinear structures whose items may be compared by a total order relation.
|
||||
|
||||
{{warning| '''Caution''': Note that the class name, chosen for brevity's sake, is slightly misleading: it is not the structures that are comparable but their items. }}
|
||||
{{caution|The class name COMPARABLE_STRUCT, chosen for brevity's sake, is slightly misleading: it is not the structures that are comparable but their items. }}
|
||||
|
||||
COMPARABLE_STRUCT introduces the features <eiffel>min</eiffel> and <eiffel>max</eiffel>, giving access to the minimum and maximum elements of a structure; these are always present for a finite <br/>
|
||||
structure with a total order relation. [[ref:/libraries/base/reference/sorted_struct_chart|SORTED_STRUCT]] , an heir of [[ref:/libraries/base/reference/comparable_struct_chart|COMPARABLE_STRUCT]] , describes structures that can be sorted; it introduces the query sorted and the command sort. <br/>
|
||||
|
||||
@@ -183,12 +183,12 @@ In particular all tuple types conform to [[ref:/libraries/base/reference/tuple_c
|
||||
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</code> [T <code>1</code>, T <code>2</code>, ..., T <code>n</code>] for any n (including 0, for which there is no generic parameter). }}
|
||||
|
||||
{{note|(Note 1: CONF1 should be understood in terms of the underlying mathematical model. Mathematically, [[ref:/libraries/base/reference/tuple_chart|TUPLE]] [T <code>1</code>, T <code>2</code>, ..., T <code>n</code>] is the set TUPLE <code>n</code> of all partial functions f from N+ (the set of non-negative integers) to T <code>1</code> U T <code>2</code> U ... T <code>n</code>, such that:
|
||||
* The domain of f contains the interval 1..n (in other words, f is defined for any i such that 1 <= i <= n).
|
||||
* For 1 <= i <= n, f (i) is a member of T <code>i</code>.
|
||||
}}
|
||||
|
||||
{{note|CONF1 should be understood in terms of the underlying mathematical model. <br/>
|
||||
Mathematically, TUPLE [T1, T2, ..., Tn] is the set TUPLE n of all partial functions f from N+ (the set of non-negative integers) to T1 U T2 U ... Tn, such that:<br/>The domain of f contains the interval 1..n (in other words, f is defined for any i such that 1 <= i <= n). <br/>For 1 <= i <= n, f (i) is a member of Ti. }}
|
||||
|
||||
With this definition, TUPLE <code>n</code> is indeed a subset of TUPLE <code>n+1</code>, and in particular TUPLE <code>0</code>, the empty set, is a subset of TUPLE <code>n</code> for any n.)
|
||||
|
||||
@@ -304,17 +304,17 @@ A few classes of the Kernel Library support file manipulation, input and output:
|
||||
FILE describes the notion of sequential file viewed as a data structure which fits in the general taxonomy of EiffelBase. <br/>
|
||||
The class declaration defines files as unbounded sequences of characters. This means that you will find in FILE all the operations on sequential data structures that you have come to know and love by reading this documentation - at least, all that apply. Just as stacks and linked lists, files have <eiffel>put</eiffel>, <eiffel>extend</eiffel>, <eiffel>has</eiffel>, <eiffel>item</eiffel> and so on. More specific to files are the typed input and output operations. For output, you will find <eiffel>put_character</eiffel>, <eiffel>put_integer</eiffel>, <eiffel>put_real</eiffel>, <eiffel>put_double</eiffel> and <eiffel>put_string</eiffel>, as well as <eiffel>new_line</eiffel>. For input you will find <eiffel>read_integer</eiffel> and its co-conspirators.
|
||||
|
||||
{{warning| '''Caution''': Note the application to input features of the command-query separation principle. <br/>
|
||||
{{caution|Note the application to input features of the command-query separation principle. <br/>
|
||||
The input features such as read_integer do not by themselves return a result; they set the values of queries such as last_integer. So the normal way to read is through two operations: <br/>
|
||||
<br/>
|
||||
<code> my_file </code> <code> . </code>read_integer <br/>
|
||||
<code> new_value </code> <code> := </code> <code> my_file </code> <code> . </code>last_integer }}
|
||||
my_file.read_integer <br/>
|
||||
new_value := my_file.last_integer }}
|
||||
|
||||
Queries are available to determine the status of a file, in particular <eiffel>exists</eiffel>, <eiffel>is_readable</eiffel>, <eiffel>is_executable</eiffel>, <eiffel>is_writable</eiffel>, <eiffel>is_creatable</eiffel>, <eiffel>is_closed</eiffel>, <eiffel>is_open_read</eiffel> and so on.
|
||||
|
||||
{{warning| '''Caution''': You will notice in the flat-short form that all these queries except the first have exists as a precondition. This precondition is good for efficiency since it saves an existence test - a relatively expensive operation - when you know that a certain file exists. But it also means that if you have any doubt about the file's existence you must use the queries in the style <br/>
|
||||
{{caution|You will notice in the flat-short form that all these queries except the first have exists as a precondition. This precondition is good for efficiency since it saves an existence test - a relatively expensive operation - when you know that a certain file exists. But it also means that if you have any doubt about the file's existence you must use the queries in the style <br/>
|
||||
<br/>
|
||||
<code> if </code> <code> my_file </code> <code> . </code>exists <code> and then </code> <code> my_file </code> <code> . </code>is_readable <code> then </code>... }}
|
||||
<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/>
|
||||
@@ -427,7 +427,7 @@ The class also provides a set of constant integer-valued attributes which denote
|
||||
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>.
|
||||
|
||||
{{warning| ''' 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. }}
|
||||
{{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.
|
||||
|
||||
@@ -444,7 +444,7 @@ Because signal codes are platform-dependent, the features of [[ref:/libraries/ba
|
||||
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.
|
||||
|
||||
{{warning| '''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 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. }}
|
||||
|
||||
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.
|
||||
|
||||
@@ -15,16 +15,16 @@ Two classes provide basic mathematical functions such as logarithms and trigonom
|
||||
|
||||
Class [[ref:/libraries/base/reference/internal_chart|INTERNAL]] provides low-level access to internal object structures. It, too, is meant to be used as ancestor by classes needing its features. <br/>
|
||||
Here are some of the most useful calls and what they yield, <eiffel>obj</eiffel> being an entity attached to an object <eiffel>O</eiffel> and <eiffel>i</eiffel> an integer:
|
||||
* [[ref:/libraries/base/reference/internal_flatshort|class_name]] (<eiffel>obj</eiffel>): the name of the generator class for O.
|
||||
* [[ref:/libraries/base/reference/internal_flatshort|dynamic_type ]] <code> ( obj ) </code>: the integer code for the type of <eiffel>O</eiffel>, where each type in a system is identified by a unique code.
|
||||
* [[ref:/libraries/base/reference/internal_flatshort|field_count ]] <code> ( obj ) </code>: the number of fields in <eiffel>O</eiffel>.
|
||||
* [[ref:/libraries/base/reference/internal_flatshort|physical_size ]] <code> ( obj ) </code>: the space occupied by <eiffel>O</eiffel>, in bytes.
|
||||
* <eiffel>field_xx</eiffel> <code> ( i, obj ) </code> where <eiffel>xx</eiffel> is name or offset: name or offset of the i-th field of <eiffel>O</eiffel>.
|
||||
* [[ref:/libraries/base/reference/internal_flatshort|field ]] <code> ( i, obj ) </code>: the value of the i-th field of , if a reference; declared of type ANY in the class.
|
||||
* <eiffel>yy_field</eiffel> <code> ( i, obj ) </code> where <eiffel>yy</eiffel> is boolean, character, integer, real or double: the value of the i-th field of <eiffel>O</eiffel>, if of the corresponding type; each declared of the appropriate type in the class.
|
||||
* [[ref:/libraries/base/reference/internal_flatshort|is_special ]] <code> ( obj ) </code>, a boolean query which indicates whether <eiffel>O</eiffel> is a special object (the sequence of values representing the elements of an array or the characters of a string).
|
||||
* <eiffel>class_name (obj)</eiffel> : the name of the generator class for O.
|
||||
* <eiffel>dynamic_type (obj) </eiffel> : the integer code for the type of <eiffel>O</eiffel>, where each type in a system is identified by a unique code.
|
||||
* <eiffel>field_count (obj) </eiffel> : the number of fields in <eiffel>O</eiffel>.
|
||||
* <eiffel>physical_size (obj) </eiffel> : the space occupied by <eiffel>O</eiffel>, in bytes.
|
||||
* <eiffel>field_xx (i, obj) </eiffel> where <eiffel>xx</eiffel> is name or offset: name or offset of the i-th field of <eiffel>O</eiffel>.
|
||||
* <eiffel>field (i, obj) </eiffel> : the value of the i-th field of , if a reference; declared of type ANY in the class.
|
||||
* <eiffel>yy_field (i, obj) </eiffel> where <eiffel>yy</eiffel> is boolean, character, integer, real or double: the value of the i-th field of <eiffel>O</eiffel>, if of the corresponding type; each declared of the appropriate type in the class.
|
||||
* <eiffel>is_special (obj) </eiffel> : a boolean query which indicates whether <eiffel>O</eiffel> is a special object (the sequence of values representing the elements of an array or the characters of a string).
|
||||
|
||||
{{warning| '''CAUTION:''' Only very special cases justify the use of this class. Unless you are writing the lowest level of an interface between an Eiffel application and external tools (such as a database management system), and this requires passing to those tools information about the internals of Eiffel objects, you almost certainly should not use [[ref:/libraries/base/reference/internal_chart|INTERNAL]] . }}
|
||||
{{warning|Only very special cases justify the use of the class [[ref:/libraries/base/reference/internal_chart|INTERNAL]]. Unless you are writing the lowest level of an interface between an Eiffel application and external tools (such as a database management system), and this requires passing to those tools information about the internals of Eiffel objects, you almost certainly should not use [[ref:/libraries/base/reference/internal_chart|INTERNAL]] . }}
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user