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
Constant Summary collapse
- VERSION =
'0.5.6'
Instance Method Summary collapse
-
#+(other) ⇒ ConcatenatedStream
Create a Stream::ConcatenatedStream by concatenating 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 {|element| ... } ⇒ MappedStream
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 {|element| ... } ⇒ FilteredStream
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 {|element| ... } ⇒ Object?
Move backward until the boolean block is not false and returns the element found.
-
#move_forward_until {|element| ... } ⇒ 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) ⇒ ConcatenatedStream
Create a Stream::ConcatenatedStream by concatenating the receiver and other_stream.
734 735 736 |
# File 'lib/stream.rb', line 734 def +(other) [self, other].create_stream.concatenate end |
#at_beginning? ⇒ Boolean
Returns false if the next #backward will return an element.
24 25 26 |
# File 'lib/stream.rb', line 24 def at_beginning? raise NotImplementedError end |
#at_end? ⇒ Boolean
Returns false if the next #forward will return an element.
19 20 21 |
# File 'lib/stream.rb', line 19 def at_end? raise NotImplementedError end |
#backward ⇒ Object
Move backward one position. Returns the source of current_edge.
40 41 42 43 44 |
# File 'lib/stream.rb', line 40 def backward raise EndOfStreamException if at_beginning? basic_backward end |
#collect {|element| ... } ⇒ MappedStream
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.
706 707 708 |
# File 'lib/stream.rb', line 706 def collect(&mapping) MappedStream.new(self, &mapping) end |
#concatenate ⇒ Object
Create a Stream::ConcatenatedStream on self, which must be a stream of streams.
712 713 714 |
# File 'lib/stream.rb', line 712 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]
723 724 725 |
# File 'lib/stream.rb', line 723 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.
154 155 156 |
# File 'lib/stream.rb', line 154 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.
110 111 112 |
# File 'lib/stream.rb', line 110 def current at_beginning? ? self : basic_current end |
#current_edge ⇒ Object
Returns the array [#current,#peek].
121 122 123 |
# File 'lib/stream.rb', line 121 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.
147 148 149 150 |
# File 'lib/stream.rb', line 147 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.
141 142 143 |
# File 'lib/stream.rb', line 141 def empty? at_end? and at_beginning? end |
#filtered {|element| ... } ⇒ FilteredStream
Return a Stream::FilteredStream which iterates over all my elements satisfying the condition specified by the block.
692 693 694 |
# File 'lib/stream.rb', line 692 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.
127 128 129 130 |
# File 'lib/stream.rb', line 127 def first set_to_begin forward end |
#forward ⇒ Object
Move forward one position. Returns the target of current_edge.
31 32 33 34 35 |
# File 'lib/stream.rb', line 31 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.
134 135 136 137 |
# File 'lib/stream.rb', line 134 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.
742 743 744 |
# File 'lib/stream.rb', line 742 def modify(&block) ImplicitStream.new(self, &block) end |
#move_backward_until {|element| ... } ⇒ Object?
Move backward until the boolean block is not false and returns the element found. Returns nil if no object matches.
100 101 102 103 104 105 106 |
# File 'lib/stream.rb', line 100 def move_backward_until until at_beginning? element = basic_backward return element if yield(element) end nil end |
#move_forward_until {|element| ... } ⇒ 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.
88 89 90 91 92 93 94 |
# File 'lib/stream.rb', line 88 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.
116 117 118 |
# File 'lib/stream.rb', line 116 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]
750 751 752 753 754 755 756 |
# File 'lib/stream.rb', line 750 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.
764 765 766 |
# File 'lib/stream.rb', line 764 def remove_last reverse.remove_first.reverse # I like this one end |
#reverse ⇒ Object
Create a Stream::ReversedStream wrapper on self.
697 698 699 |
# File 'lib/stream.rb', line 697 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.
48 49 50 |
# File 'lib/stream.rb', line 48 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.
54 55 56 |
# File 'lib/stream.rb', line 54 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.
160 161 162 |
# File 'lib/stream.rb', line 160 def unwrapped self end |