mirror of
https://github.com/EiffelSoftware/eiffel-org.git
synced 2025-12-06 14:52:03 +01:00
- remove '>' in "(customers.item>) "
- corrected link to LINEAR_ITERATOR - replace code for 'An example iterator routine' - added link to 'target' to point to the correct place in LINEAR_ITERATOR chart - Modified "An example use of iteration" to conform to current implementation using agents. -- TODO -- Continue work from =Using the Iteration Library= Updated wikipage EiffelBase, Iteration. (Signed-off-by:WilliamsLima). git-svn-id: https://svn.eiffel.com/eiffel-org/trunk@2074 abb3cda0-5349-4a8f-a601-0c33ac3a8c38
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
[[Property:modification_date|Wed, 12 Sep 2018 13:40:39 GMT]]
|
||||
[[Property:publication_date|Wed, 12 Sep 2018 13:40:39 GMT]]
|
||||
[[Property:title|EiffelBase, Iteration]]
|
||||
[[Property:weight|6]]
|
||||
[[Property:uuid|9c0313bf-571d-0c8d-5c49-8bd99f86bed5]]
|
||||
@@ -38,8 +40,8 @@ then a class <eiffel>SPECIAL_PROMOTION</eiffel> of a text processing system may
|
||||
until
|
||||
customers.exhausted
|
||||
loop
|
||||
if recent_purchases.has (customers.item>) then
|
||||
target_list.put (customers.item>)
|
||||
if recent_purchases.has (customers.item) then
|
||||
target_list.put (customers.item)
|
||||
end
|
||||
customers.forth
|
||||
end</code>
|
||||
@@ -55,49 +57,54 @@ To get a first grasp of how one can work with the Iteration library, let us look
|
||||
|
||||
==An example iterator routine==
|
||||
|
||||
Here, given with its full implementation, is a typical Iteration library routine: the procedure until_do from [[ref:libraries/base/reference/linear_iterator_chart]] , the class defining iteration mechanisms on linear (sequential) structures.
|
||||
Here, given with its full implementation, is a typical Iteration library routine: the procedure until_do from [[ref:libraries/base/reference/linear_iterator_chart|LINEAR_ITERATOR]] , the class defining iteration mechanisms on linear (sequential) structures.
|
||||
<code>
|
||||
until_do
|
||||
-- Apply action to every item of target,
|
||||
-- up to but excluding first one satisfying test.
|
||||
-- (Apply to full list if no item satisfies test.)
|
||||
require
|
||||
traversable_exists: target /= Void
|
||||
do
|
||||
from
|
||||
target.start
|
||||
invariant
|
||||
''invariant_value''
|
||||
until
|
||||
target.exhausted or else test
|
||||
loop
|
||||
action
|
||||
target.forth
|
||||
end
|
||||
ensure
|
||||
achieved: target.exhausted or else test
|
||||
invariant_satisfied: ''invariant_value''
|
||||
end</code>
|
||||
until_do (action: PROCEDURE [G]; test: FUNCTION [G, BOOLEAN])
|
||||
-- Apply `action' to every item of `target' up to
|
||||
-- but excluding first one satisfying `test'.
|
||||
-- (Apply to full list if no item satisfies `test'.)
|
||||
do
|
||||
start
|
||||
until_continue (action, test)
|
||||
ensure then
|
||||
achieved: not exhausted implies test.item ([target.item])
|
||||
end
|
||||
|
||||
The precise form of the procedure in the class relies on a call to another procedure, until_continue, and on inherited assertions. Here everything has been unfolded for illustration purposes. <br/>
|
||||
This procedure will traverse the linear structure identified by target and apply the procedure calledaction on every item up to but excluding the first one satisfying test. <br/>
|
||||
until_continue (action: PROCEDURE [G]; test: FUNCTION [G, BOOLEAN])
|
||||
-- Apply `action' to every item of `target' from current
|
||||
-- position, up to but excluding first one satisfying `test'.
|
||||
require
|
||||
invariant_satisfied: invariant_value
|
||||
do
|
||||
from
|
||||
invariant
|
||||
invariant_value
|
||||
until
|
||||
exhausted or else test.item ([target.item])
|
||||
loop
|
||||
action.call ([item])
|
||||
forth
|
||||
end
|
||||
ensure
|
||||
achieved: exhausted or else test.item ([target.item])
|
||||
invariant_satisfied: invariant_value
|
||||
end
|
||||
</code>
|
||||
|
||||
The precise form of the procedure in the class relies on a call to another procedure, until_continue, and on inherited assertions. Here the routines are shown as they are found in the current implementation of the class [[ref:libraries/base/reference/linear_iterator_chart|LINEAR_ITERATOR]]. <br/>
|
||||
This procedure will traverse the linear structure identified by [[ref:libraries/base/linear_iterator_flatshort.html#f_target|target]] and apply the procedure called action on every item up to but excluding the first one satisfying test. <br/>
|
||||
The class similarly offers <eiffel>do_all</eiffel>, <eiffel>do_while</eiffel>, <eiffel>do_for</eiffel>, <eiffel>do_if</eiffel> and other procedures representing the common control structures. It also includes functions such as <eiffel>exists</eiffel> and <eiffel>forall</eiffel>, corresponding to the usual quantifiers. <br/>
|
||||
These iteration schemes depend on the procedure <eiffel>action</eiffel>, defining the action to be applied to successive elements, and on the function <eiffel>test</eiffel>, defining the boolean query to be applied to these elements. These features are declared in class [[ref:libraries/base/reference/iterator_chart|ITERATOR]] (the highest-level deferred class of the Iteration library); here is <eiffel>test</eiffel>:
|
||||
<code>
|
||||
test: BOOLEAN
|
||||
-- Test to be applied to item at current position in
|
||||
-- target (default: value of item_test on item)
|
||||
require
|
||||
traversable_exists: target /= Void
|
||||
not_off: not target.off
|
||||
These iteration schemes depend on the procedure <eiffel>action</eiffel>, defining the action to be applied to successive elements, and on the function <eiffel>test</eiffel>, defining the boolean query to be applied to these elements. Both routines are used trough the Eiffel's agent mechanism; here is an example of a <eiffel>test</eiffel>
|
||||
function intended to be used with iteration over a data structure whose elements are <code>STRING</code>s.
|
||||
<code>
|
||||
test (a_item: STRING): BOOLEAN
|
||||
-- Test to be applied to a_item
|
||||
do
|
||||
Result := item_test (target.item>)
|
||||
ensure
|
||||
not_off: not target.off
|
||||
end</code>
|
||||
Result := a_item.count > 0
|
||||
end
|
||||
</code>
|
||||
|
||||
This indicates that the value of the boolean function <eiffel>test</eiffel> will be obtained by applying <eiffel>item_test</eiffel> to the item at the current position in the target structure. In [[ref:libraries/base/reference/iterator_chart|ITERATOR]] , function <eiffel>item_test</eiffel> always return ; descendant classes will redefine it so as to describe the desired test. Similarly, <eiffel>action</eiffel> is declared in class [[ref:libraries/base/reference/iterator_chart|ITERATOR]] as a call to <eiffel>item_action</eiffel>. Descendants will redefine <eiffel>item_action</eiffel>, which as initially declared in [[ref:libraries/base/reference/iterator_chart|ITERATOR]] is a procedure with a null body. <br/>
|
||||
Going through <eiffel>item_action</eiffel> and <eiffel>item_test</eiffel> provides an extra degree of flexibility. Normally the action and test performed at each step apply to <eiffel>target</eiffel> <code> . </code><eiffel>item></eiffel>, so that it suffices to redefine the <eiffel>item_features</eiffel>. This is the case with all examples studied in this chapter. In a more general setting, however, you might need to redefine <eiffel>action</eiffel> and <eiffel>test</eiffel> themselves.
|
||||
This indicates that the value of the boolean function <eiffel>test</eiffel> will be obtained by verifying that <eiffel>a_item</eiffel> is an empty string or not.
|
||||
|
||||
==An example use of iteration==
|
||||
|
||||
@@ -119,10 +126,7 @@ class
|
||||
TEXT_PROCESSOR
|
||||
|
||||
inherit
|
||||
LINEAR_ITERATOR [PARAGRAPH]
|
||||
redefine
|
||||
item_action, item_test
|
||||
end
|
||||
LINEAR_ITERATOR [PARAGRAPH]
|
||||
|
||||
feature
|
||||
|
||||
@@ -131,12 +135,12 @@ feature
|
||||
-- the first one that has been modified.
|
||||
do
|
||||
set (t)
|
||||
until_do
|
||||
until_do (agent item_action, agent item_test)
|
||||
end
|
||||
|
||||
feature {NONE}
|
||||
|
||||
item_test (p PARAGRAPH): BOOLEAN
|
||||
item_test (p: PARAGRAPH): BOOLEAN
|
||||
-- Has p been modified?
|
||||
do
|
||||
Result := p.modified
|
||||
@@ -154,9 +158,9 @@ Thanks to the iteration mechanism, the procedure <eiffel>resize_paragraphs</eiff
|
||||
* To set its argument <code>t</code> as the iteration target, it uses procedure <eiffel>set</eiffel>. (This procedure is from class [[ref:libraries/base/reference/iterator_chart|ITERATOR]] which passes it on to all iterator classes.)
|
||||
* Then it simply calls <eiffel>until_do</eiffel> as defined above.
|
||||
|
||||
Procedure <eiffel>item_action</eiffel> is redefined to describe the operation to be performed on each successive element. Function <eiffel>item_test</eiffel> is redefined to describe the exit test. <br/>
|
||||
Procedure <eiffel>item_action</eiffel> is defined to describe the operation to be performed on each successive element. Function <eiffel>item_test</eiffel> is defined to describe the exit test. <br/>
|
||||
As presented so far, the mechanism seems to limit every descendant of an iteration class to just one form of iteration. As shown later in this chapter, it is in fact easy to generalize the technique to allow a class to use an arbitrary number of iteration schemes. <br/>
|
||||
What is interesting here is that the redefinitions of <eiffel>item_test</eiffel> and <eiffel>item_action</eiffel> take care of all the details. There is no need to write any loop or other control structure. We are at the very heart of the object-oriented method, enjoying the ability to encapsulate useful and common software schemes so that client developers will only need to fill in what is specific to their application.
|
||||
What is interesting here is that the definitions of <eiffel>item_test</eiffel> and <eiffel>item_action</eiffel> take care of all the details. There is no need to write any loop or other control structure. We are at the very heart of the object-oriented method, enjoying the ability to encapsulate useful and common software schemes so that client developers will only need to fill in what is specific to their application.
|
||||
|
||||
=Using the Iteration Library=
|
||||
|
||||
|
||||
Reference in New Issue
Block a user