Module: Stream
Overview
Module Stream defines an interface for an external Iterator which can move forward and backwards. See README for more information.
The functionality is similar to Smalltalk’s ReadStream.
Defined Under Namespace
Classes: BasicStream, CollectionStream, ConcatenatedStream, EmptyStream, EndOfStreamException, FilteredStream, ImplicitStream, IntervalStream, MappedStream, ReversedStream, WrappedStream
Instance Method Summary collapse
-
#+(other) ⇒ Object
Create a Stream::ConcatenatedStream by concatenatating the receiver and other_stream.
-
#at_beginning? ⇒ Boolean
Returns false if the next #backward will return an element.
-
#at_end? ⇒ Boolean
Returns false if the next #forward will return an element.
-
#backward ⇒ Object
Move backward one position.
-
#collect(&mapping) ⇒ Object
Create a Stream::MappedStream wrapper on self.
-
#concatenate ⇒ Object
Create a Stream::ConcatenatedStream on self, which must be a stream of streams.
-
#concatenate_collected(&mapping) ⇒ Object
Create a Stream::ConcatenatedStream, concatenated from streams build with the block for each element of self:.
-
#create_stream ⇒ Object
create_stream is used for each Enumerable to create a stream for it.
-
#current ⇒ Object
Returns the element returned by the last call of #forward.
-
#current_edge ⇒ Object
Returns the array [#current,#peek].
-
#each ⇒ Object
Implements the standard iterator used by module Enumerable, by calling set_to_begin and basic_forward until at_end? is true.
-
#empty? ⇒ Boolean
Returns true if the stream is empty which is equivalent to at_end? and at_beginning? both being true.
-
#filtered(&block) ⇒ Object
Return a Stream::FilteredStream which iterates over all my elements satisfying the condition specified by the block.
-
#first ⇒ Object
Returns the first element of the stream.
-
#forward ⇒ Object
Move forward one position.
-
#last ⇒ Object
Returns the last element of the stream.
-
#modify(&block) ⇒ Object
Create a Stream::ImplicitStream which wraps the receiver stream by modifying one or more basic methods of the receiver.
-
#move_backward_until ⇒ Object
Move backward until the boolean block is not false and returns the element found.
-
#move_forward_until ⇒ Object
Move forward until the boolean block is not false and returns the element found.
-
#peek ⇒ Object
Returns the element returned by the last call of #backward.
-
#remove_first ⇒ Object
Returns a Stream::ImplicitStream wrapping a Stream::FilteredStream, which eliminates the first element of the receiver.
-
#remove_last ⇒ Object
Returns a Stream which eliminates the first element of the receiver.
-
#reverse ⇒ Object
Create a Stream::ReversedStream wrapper on self.
-
#set_to_begin ⇒ Object
Position the stream before its first element, i.e.
-
#set_to_end ⇒ Object
Position the stream behind its last element, i.e.
-
#unwrapped ⇒ Object
A Stream::WrappedStream should return the wrapped stream unwrapped.
Instance Method Details
#+(other) ⇒ Object
Create a Stream::ConcatenatedStream by concatenatating the receiver and other_stream
(%w(a b c).create_stream + [4,5].create_stream).to_a
==> ["a", "b", "c", 4, 5]
716 717 718 |
# File 'lib/stream.rb', line 716 def +(other) [self, other].create_stream.concatenate end |
#at_beginning? ⇒ Boolean
Returns false if the next #backward will return an element.
22 23 24 |
# File 'lib/stream.rb', line 22 def at_beginning? raise NotImplementedError end |
#at_end? ⇒ Boolean
Returns false if the next #forward will return an element.
17 18 19 |
# File 'lib/stream.rb', line 17 def at_end? raise NotImplementedError end |
#backward ⇒ Object
Move backward one position. Returns the source of current_edge. Raises Stream::EndOfStreamException if at_beginning? is true.
36 37 38 39 40 |
# File 'lib/stream.rb', line 36 def backward raise EndOfStreamException if at_beginning? basic_backward end |
#collect(&mapping) ⇒ Object
Create a Stream::MappedStream wrapper on self. Instead of returning the stream element on each move, the value of calling mapping is returned instead. See Stream::MappedStream for examples.
690 691 692 |
# File 'lib/stream.rb', line 690 def collect(&mapping) MappedStream.new(self, &mapping) end |
#concatenate ⇒ Object
Create a Stream::ConcatenatedStream on self, which must be a stream of streams.
696 697 698 |
# File 'lib/stream.rb', line 696 def concatenate ConcatenatedStream.new self end |
#concatenate_collected(&mapping) ⇒ Object
Create a Stream::ConcatenatedStream, concatenated from streams build with the block for each element of self:
s = [1, 2, 3].create_stream.concatenate_collected { |i|
[i,-i].create_stream
}.
s.to_a ==> [1, -1, 2, -2, 3, -3]
707 708 709 |
# File 'lib/stream.rb', line 707 def concatenate_collected(&mapping) collect(&mapping).concatenate end |
#create_stream ⇒ Object
create_stream is used for each Enumerable to create a stream for it. A Stream as an Enumerable returns itself.
146 147 148 |
# File 'lib/stream.rb', line 146 def create_stream self end |
#current ⇒ Object
Returns the element returned by the last call of #forward. If at_beginning? is true self is returned.
102 103 104 |
# File 'lib/stream.rb', line 102 def current at_beginning? ? self : basic_current end |
#current_edge ⇒ Object
Returns the array [#current,#peek].
113 114 115 |
# File 'lib/stream.rb', line 113 def current_edge [current, peek] end |
#each ⇒ Object
Implements the standard iterator used by module Enumerable, by calling set_to_begin and basic_forward until at_end? is true.
139 140 141 142 |
# File 'lib/stream.rb', line 139 def each set_to_begin yield basic_forward until at_end? end |
#empty? ⇒ Boolean
Returns true if the stream is empty which is equivalent to at_end? and at_beginning? both being true.
133 134 135 |
# File 'lib/stream.rb', line 133 def empty? at_end? and at_beginning? end |
#filtered(&block) ⇒ Object
Return a Stream::FilteredStream which iterates over all my elements satisfying the condition specified by the block.
678 679 680 |
# File 'lib/stream.rb', line 678 def filtered(&block) FilteredStream.new(self, &block) end |
#first ⇒ Object
Returns the first element of the stream. This is accomplished by calling set_to_begin and #forward, which means a state change.
119 120 121 122 |
# File 'lib/stream.rb', line 119 def first set_to_begin forward end |
#forward ⇒ Object
Move forward one position. Returns the target of current_edge. Raises Stream::EndOfStreamException if at_end? is true.
28 29 30 31 32 |
# File 'lib/stream.rb', line 28 def forward raise EndOfStreamException if at_end? basic_forward end |
#last ⇒ Object
Returns the last element of the stream. This is accomplished by calling set_to_begin and #backward, which means a state change.
126 127 128 129 |
# File 'lib/stream.rb', line 126 def last set_to_end backward end |
#modify(&block) ⇒ Object
Create a Stream::ImplicitStream which wraps the receiver stream by modifying one or more basic methods of the receiver. As an example the method remove_first uses #modify to create an ImplicitStream which filters the first element away.
724 725 726 |
# File 'lib/stream.rb', line 724 def modify(&block) ImplicitStream.new(self, &block) end |
#move_backward_until ⇒ Object
Move backward until the boolean block is not false and returns the element found. Returns nil if no object matches.
92 93 94 95 96 97 98 |
# File 'lib/stream.rb', line 92 def move_backward_until until at_beginning? element = basic_backward return element if yield(element) end nil end |
#move_forward_until ⇒ Object
Move forward until the boolean block is not false and returns the element found. Returns nil if no object matches.
This is similar to #detect, but starts the search from the current position. #detect, which is inherited from Enumerable uses #each, which implicitly calls #set_to_begin.
82 83 84 85 86 87 88 |
# File 'lib/stream.rb', line 82 def move_forward_until until at_end? element = basic_forward return element if yield(element) end nil end |
#peek ⇒ Object
Returns the element returned by the last call of #backward. If at_end? is true self is returned.
108 109 110 |
# File 'lib/stream.rb', line 108 def peek at_end? ? self : basic_peek end |
#remove_first ⇒ Object
Returns a Stream::ImplicitStream wrapping a Stream::FilteredStream, which eliminates the first element of the receiver.
(1..3).create_stream.remove_first.to_a ==> [2,3]
732 733 734 735 736 737 738 |
# File 'lib/stream.rb', line 732 def remove_first i = 0 filter = filtered { i += 1; i > 1 } filter.modify do |s| s.set_to_begin_proc = proc { filter.set_to_begin; i = 0 } end end |
#remove_last ⇒ Object
Returns a Stream which eliminates the first element of the receiver.
(1..3).create_stream.remove_last.to_a ==> [1,2]
Take a look at the source. The implementation is inefficient but elegant.
746 747 748 |
# File 'lib/stream.rb', line 746 def remove_last reverse.remove_first.reverse # I like this one end |
#reverse ⇒ Object
Create a Stream::ReversedStream wrapper on self.
683 684 685 |
# File 'lib/stream.rb', line 683 def reverse ReversedStream.new self end |
#set_to_begin ⇒ Object
Position the stream before its first element, i.e. the next #forward will return the first element.
44 45 46 |
# File 'lib/stream.rb', line 44 def set_to_begin basic_backward until at_beginning? end |
#set_to_end ⇒ Object
Position the stream behind its last element, i.e. the next #backward will return the last element.
50 51 52 |
# File 'lib/stream.rb', line 50 def set_to_end basic_forward until at_end? end |
#unwrapped ⇒ Object
A Stream::WrappedStream should return the wrapped stream unwrapped. If the stream is not a wrapper around another stream it simply returns itself.
152 153 154 |
# File 'lib/stream.rb', line 152 def unwrapped self end |