help-smalltalk
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Help-smalltalk] [PATCH] Provide a common superclass of Collection and S


From: Paolo Bonzini
Subject: [Help-smalltalk] [PATCH] Provide a common superclass of Collection and Stream
Date: Tue, 05 Aug 2008 10:38:52 +0200
User-agent: Thunderbird 2.0.0.16 (Macintosh/20080707)

The class is called Iterable and it implements, together with #do:, some more methods (a few of which are currently duplicated in the two hierarchies). More will come later.

Paolo
diff --git a/kernel/Collection.st b/kernel/Collection.st
index 2848690..47c8eb2 100644
--- a/kernel/Collection.st
+++ b/kernel/Collection.st
@@ -32,7 +32,7 @@
 
 
 
-Object subclass: Collection [
+Iterable subclass: Collection [
     
     <category: 'Collections'>
     <comment: 'I am an abstract class.  My instances are collections of 
objects.  My
@@ -316,26 +316,6 @@ of objects.'>
        ^Generator on: self do: [ :gen :each | gen yield: each ]
     ]
 
-    do: aBlock [
-       "Enumerate each object of the receiver, passing them to aBlock"
-
-       <category: 'enumeration'>
-       self subclassResponsibility
-    ]
-
-    do: aBlock separatedBy: separatorBlock [
-       "Enumerate each object of the receiver, passing them to aBlock.
-        Between every two invocations of aBlock, invoke separatorBlock"
-
-       <category: 'enumeration'>
-       | first |
-       first := true.
-       self do: 
-               [:each | 
-               first ifTrue: [first := false] ifFalse: [separatorBlock value].
-               aBlock value: each]
-    ]
-
     select: aBlock [
        "Answer a new instance of a Collection containing all the elements
         in the receiver which, when passed to aBlock, answer true"
@@ -371,27 +351,6 @@ of objects.'>
        ^newCollection
     ]
 
-    detect: aBlock ifNone: exceptionBlock [
-       "Search the receiver for an element for which aBlock returns true.
-        If some does, answer it. If none does, answer the result of evaluating
-        aBlock"
-
-       <category: 'enumeration'>
-       self do: [:element | (aBlock value: element) ifTrue: [^element]].
-       ^exceptionBlock value
-    ]
-
-    count: aBlock [
-       "Count the elements of the receiver for which aBlock returns true,
-        and return their number."
-
-       <category: 'enumeration'>
-       | count |
-       count := 0.
-       self do: [:element | (aBlock value: element) ifTrue: [count := count + 
1]].
-       ^count
-    ]
-
     gather: aBlock [
        "Answer a new instance of a Collection containing all the results
         of evaluating aBlock, joined together.  aBlock should return
@@ -402,91 +361,6 @@ of objects.'>
        ^(self collect: aBlock) join
     ]
 
-    allSatisfy: aBlock [
-       "Search the receiver for an element for which aBlock returns false.
-        Answer true if none does, false otherwise."
-
-       <category: 'enumeration'>
-       self do: [:element | (aBlock value: element) ifFalse: [^false]].
-       ^true
-    ]
-
-    noneSatisfy: aBlock [
-       "Search the receiver for an element for which aBlock returns true.
-        Answer true if none does, false otherwise."
-
-       <category: 'enumeration'>
-       self do: [:element | (aBlock value: element) ifTrue: [^false]].
-       ^true
-    ]
-
-    anySatisfy: aBlock [
-       "Search the receiver for an element for which aBlock returns true.
-        Answer true if some does, false otherwise."
-
-       <category: 'enumeration'>
-       self do: [:element | (aBlock value: element) ifTrue: [^true]].
-       ^false
-    ]
-
-    conform: aBlock [
-       "Search the receiver for an element for which aBlock returns false.
-        Answer true if none does, false otherwise."
-
-       <category: 'enumeration'>
-       self do: [:element | (aBlock value: element) ifFalse: [^false]].
-       ^true
-    ]
-
-    contains: aBlock [
-       "Search the receiver for an element for which aBlock returns true.
-        Answer true if some does, false otherwise."
-
-       <category: 'enumeration'>
-       self do: [:element | (aBlock value: element) ifTrue: [^true]].
-       ^false
-    ]
-
-    detect: aBlock [
-       "Search the receiver for an element for which aBlock returns true.
-        If some does, answer it. If none does, fail"
-
-       <category: 'enumeration'>
-       ^self detect: aBlock
-           ifNone: [SystemExceptions.NotFound signal: 'object not found']
-    ]
-
-    fold: binaryBlock [
-       "First, pass to binaryBlock the first and second elements of the
-        receiver; for each subsequent element, pass the result of the previous
-        evaluation and an element. Answer the result of the last invocation,
-        or the first element if the collection has size 1.  Fail if the 
collection
-        is empty."
-
-       <category: 'enumeration'>
-       | result marker |
-       self isEmpty ifTrue: [^SystemExceptions.EmptyCollection signalOn: self].
-       result := marker := Object new.
-       self do: 
-               [:element | 
-               result := result == marker 
-                           ifTrue: [element]
-                           ifFalse: [binaryBlock value: result value: 
element]].
-       ^result
-    ]
-
-    inject: thisValue into: binaryBlock [
-       "First, pass to binaryBlock thisValue and the first element of the
-        receiver; for each subsequent element, pass the result of the previous
-        evaluation and an element. Answer the result of the last invocation."
-
-       <category: 'enumeration'>
-       | result |
-       result := thisValue.
-       self do: [:element | result := binaryBlock value: result value: 
element].
-       ^result
-    ]
-
     asArray [
        "Answer an Array containing all the elements in the receiver"
 
diff --git a/kernel/Iterable.st b/kernel/Iterable.st
new file mode 100644
index 0000000..71f93ef
--- /dev/null
+++ b/kernel/Iterable.st
@@ -0,0 +1,205 @@
+"======================================================================
+|
+|   Iterable Method Definitions
+|
+|
+ ======================================================================"
+
+"======================================================================
+|
+| Copyright 2008 Free Software Foundation, Inc.
+| Written by Paolo Bonzini.
+|
+| This file is part of the GNU Smalltalk class library.
+|
+| The GNU Smalltalk class library is free software; you can redistribute it
+| and/or modify it under the terms of the GNU Lesser General Public License
+| as published by the Free Software Foundation; either version 2.1, or (at
+| your option) any later version.
+| 
+| The GNU Smalltalk class library is distributed in the hope that it will be
+| useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser
+| General Public License for more details.
+| 
+| You should have received a copy of the GNU Lesser General Public License
+| along with the GNU Smalltalk class library; see the file COPYING.LIB.
+| If not, write to the Free Software Foundation, 59 Temple Place - Suite
+| 330, Boston, MA 02110-1301, USA.  
+|
+ ======================================================================"
+
+
+
+Object subclass: Iterable [
+    
+    <category: 'Collections'>
+    <comment: 'I am an abstract class.  My instances are collections of objects
+that can be iterated.  The details on how they can be mutated (if at
+all possible) are left to the subclasses.'>
+
+    Iterable class >> isUnicode [
+       "Answer true; the receiver is able to store arbitrary
+        Unicode characters."
+
+       <category: 'multibyte encodings'>
+       self subclassResponsibility
+    ]
+
+    readStream [
+        "Answer a stream that gives elements of the receiver"
+
+       <category: 'enumeration'>
+       self subclassResponsibility
+    ]
+
+    do: aBlock [
+       "Enumerate each object of the receiver, passing them to aBlock"
+
+       <category: 'enumeration'>
+       self subclassResponsibility
+    ]
+
+    do: aBlock separatedBy: separatorBlock [
+       "Enumerate each object of the receiver, passing them to aBlock.
+        Between every two invocations of aBlock, invoke separatorBlock"
+
+       <category: 'enumeration'>
+       | first |
+       first := true.
+       self do: 
+               [:each | 
+               first ifTrue: [first := false] ifFalse: [separatorBlock value].
+               aBlock value: each]
+    ]
+
+    select: aBlock [
+       "Answer a new instance of a Collection containing all the elements
+        in the receiver which, when passed to aBlock, answer true"
+
+       <category: 'enumeration'>
+       self subclassResponsibility
+    ]
+
+    reject: aBlock [
+       "Answer a new instance of a Collection containing all the elements
+        in the receiver which, when passed to aBlock, don't answer true"
+
+       <category: 'enumeration'>
+       self subclassResponsibility
+    ]
+
+    collect: aBlock [
+       "Answer a new instance of a Collection containing all the results
+        of evaluating aBlock passing each of the receiver's elements"
+
+       <category: 'enumeration'>
+       self subclassResponsibility
+    ]
+
+    detect: aBlock ifNone: exceptionBlock [
+       "Search the receiver for an element for which aBlock returns true.
+        If some does, answer it. If none does, answer the result of evaluating
+        aBlock"
+
+       <category: 'enumeration'>
+       self do: [:element | (aBlock value: element) ifTrue: [^element]].
+       ^exceptionBlock value
+    ]
+
+    count: aBlock [
+       "Count the elements of the receiver for which aBlock returns true,
+        and return their number."
+
+       <category: 'enumeration'>
+       | count |
+       count := 0.
+       self do: [:element | (aBlock value: element) ifTrue: [count := count + 
1]].
+       ^count
+    ]
+
+    allSatisfy: aBlock [
+       "Search the receiver for an element for which aBlock returns false.
+        Answer true if none does, false otherwise."
+
+       <category: 'enumeration'>
+       self do: [:element | (aBlock value: element) ifFalse: [^false]].
+       ^true
+    ]
+
+    noneSatisfy: aBlock [
+       "Search the receiver for an element for which aBlock returns true.
+        Answer true if none does, false otherwise."
+
+       <category: 'enumeration'>
+       self do: [:element | (aBlock value: element) ifTrue: [^false]].
+       ^true
+    ]
+
+    anySatisfy: aBlock [
+       "Search the receiver for an element for which aBlock returns true.
+        Answer true if some does, false otherwise."
+
+       <category: 'enumeration'>
+       self do: [:element | (aBlock value: element) ifTrue: [^true]].
+       ^false
+    ]
+
+    conform: aBlock [
+       "Search the receiver for an element for which aBlock returns false.
+        Answer true if none does, false otherwise."
+
+       <category: 'enumeration'>
+       self do: [:element | (aBlock value: element) ifFalse: [^false]].
+       ^true
+    ]
+
+    contains: aBlock [
+       "Search the receiver for an element for which aBlock returns true.
+        Answer true if some does, false otherwise."
+
+       <category: 'enumeration'>
+       self do: [:element | (aBlock value: element) ifTrue: [^true]].
+       ^false
+    ]
+
+    detect: aBlock [
+       "Search the receiver for an element for which aBlock returns true.
+        If some does, answer it. If none does, fail"
+
+       <category: 'enumeration'>
+       ^self detect: aBlock
+           ifNone: [SystemExceptions.NotFound signal: 'object not found']
+    ]
+
+    fold: binaryBlock [
+       "First, pass to binaryBlock the first and second elements of the
+        receiver; for each subsequent element, pass the result of the previous
+        evaluation and an element. Answer the result of the last invocation,
+        or the first element if the collection has size 1.  Fail if the 
collection
+        is empty."
+
+       <category: 'enumeration'>
+       | result marker |
+       self isEmpty ifTrue: [^SystemExceptions.EmptyCollection signalOn: self].
+       result := marker := Object new.
+       self do: 
+               [:element | 
+               result := result == marker 
+                           ifTrue: [element]
+                           ifFalse: [binaryBlock value: result value: 
element]].
+       ^result
+    ]
+
+    inject: thisValue into: binaryBlock [
+       "First, pass to binaryBlock thisValue and the first element of the
+        receiver; for each subsequent element, pass the result of the previous
+        evaluation and an element. Answer the result of the last invocation."
+
+       <category: 'enumeration'>
+       | result |
+       result := thisValue.
+       self do: [:element | result := binaryBlock value: result value: 
element].
+       ^result
+    ]
+]
diff --git a/kernel/Stream.st b/kernel/Stream.st
index 32ca159..b366db0 100644
--- a/kernel/Stream.st
+++ b/kernel/Stream.st
@@ -32,7 +32,7 @@
 
 
 
-Object subclass: Stream [
+Iterable subclass: Stream [
     
     <category: 'Streams'>
     <comment: 'I am an abstract class that provides interruptable sequential 
access to
diff --git a/kernel/StreamOps.st b/kernel/StreamOps.st
index 9c6e4d1..118bfe5 100644
--- a/kernel/StreamOps.st
+++ b/kernel/StreamOps.st
@@ -669,32 +669,6 @@ Stream extend [
        ^self peekFor: aCharacter
     ]
 
-    fold: aBlock [
-       "First, pass to binaryBlock the first and second elements of the
-        receiver; for each subsequent element, pass the result of the previous
-        evaluation and an element. Answer the result of the last invocation,
-        or the first element if the stream has a single element."
-
-       <category: 'filtering'>
-       | result |
-       result := self next.
-       [self atEnd] whileFalse: [result := aBlock value: result value: self 
next].
-       ^result
-    ]
-
-    inject: value into: aBlock [
-       "First, pass to binaryBlock value and the first element of the
-        receiver; for each subsequent element, pass the result of the previous
-        evaluation and an element. Answer the result of the last invocation,
-        or value if the stream is empty."
-
-       <category: 'filtering'>
-       | result |
-       result := value.
-       [self atEnd] whileFalse: [result := aBlock value: result value: self 
next].
-       ^result
-    ]
-
     select: aBlock [
        "Answer a new stream that only returns those objects for which aBlock
         returns true.  Note that the returned stream will not be positionable."
diff --git a/libgst/dict.c b/libgst/dict.c
index 3871ed6..ac3ed14 100644
--- a/libgst/dict.c
+++ b/libgst/dict.c
@@ -124,6 +124,7 @@ OOP _gst_identity_dictionary_class = NULL;
 OOP _gst_identity_set_class = NULL;
 OOP _gst_integer_class = NULL;
 OOP _gst_interval_class = NULL;
+OOP _gst_iterable_class = NULL;
 OOP _gst_large_integer_class = NULL;
 OOP _gst_large_negative_integer_class = NULL;
 OOP _gst_large_positive_integer_class = NULL;
@@ -434,7 +435,11 @@ static const class_definition class_info[] = {
    GST_ISP_FIXED, true, 1,
    "SymLink", "symbol", NULL, NULL },
 
-  {&_gst_collection_class, &_gst_object_class,
+  {&_gst_iterable_class, &_gst_object_class,
+   GST_ISP_FIXED, false, 0,
+   "Iterable", NULL, NULL, NULL },
+
+  {&_gst_collection_class, &_gst_iterable_class,
    GST_ISP_FIXED, false, 0,
    "Collection", NULL, NULL, NULL },
 
@@ -593,7 +598,7 @@ static const class_definition class_info[] = {
    GST_ISP_POINTER, false, 0,
    "SystemDictionary", NULL, NULL, NULL },
 
-  {&_gst_stream_class, &_gst_object_class,
+  {&_gst_stream_class, &_gst_iterable_class,
    GST_ISP_FIXED, false, 0,
    "Stream", NULL, NULL, NULL },
 
diff --git a/libgst/dict.h b/libgst/dict.h
index e01293e..438f091 100644
--- a/libgst/dict.h
+++ b/libgst/dict.h
@@ -381,6 +381,7 @@ extern OOP _gst_homed_association_class ATTRIBUTE_HIDDEN;
 extern OOP _gst_identity_dictionary_class ATTRIBUTE_HIDDEN;
 extern OOP _gst_identity_set_class ATTRIBUTE_HIDDEN;
 extern OOP _gst_integer_class ATTRIBUTE_HIDDEN;
+extern OOP _gst_iterable_class ATTRIBUTE_HIDDEN;
 extern OOP _gst_interval_class ATTRIBUTE_HIDDEN;
 extern OOP _gst_large_integer_class ATTRIBUTE_HIDDEN;
 extern OOP _gst_large_negative_integer_class ATTRIBUTE_HIDDEN;
diff --git a/libgst/files.c b/libgst/files.c
index 6d3736b..0afb81b 100644
--- a/libgst/files.c
+++ b/libgst/files.c
@@ -188,14 +188,15 @@ static const char standard_files[] = {
   "Link.st\0"
   "Process.st\0"
   "CallinProcess.st\0"
-  "CompildCode.st\0"
-  "CompildMeth.st\0"
-  "CompiledBlk.st\0"
+  "Iterable.st\0"
   "Collection.st\0"
   "SeqCollect.st\0"
   "LinkedList.st\0"
   "Semaphore.st\0"
   "ArrayColl.st\0"
+  "CompildCode.st\0"
+  "CompildMeth.st\0"
+  "CompiledBlk.st\0"
   "Array.st\0"
   "ByteArray.st\0"
   "CharArray.st\0"
diff --git a/packages.xml b/packages.xml
index 9e7b75a..5a820f5 100644
--- a/packages.xml
+++ b/packages.xml
@@ -83,6 +83,7 @@
   <file>CompildMeth.st</file>
   <file>LookupTable.st</file>
   <file>RunArray.st</file>
+  <file>Iterable.st</file>
   <file>ArrayColl.st</file>
   <file>CompiledBlk.st</file>
   <file>Magnitude.st</file>

reply via email to

[Prev in Thread] Current Thread [Next in Thread]