module Stream

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.

Public Instance Methods

+(other) click to toggle source

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]
    # File lib/stream.rb
716 def +(other)
717   [self, other].create_stream.concatenate
718 end
at_beginning?() click to toggle source

Returns false if the next backward will return an element.

   # File lib/stream.rb
22 def at_beginning?
23   raise NotImplementedError
24 end
at_end?() click to toggle source

Returns false if the next forward will return an element.

   # File lib/stream.rb
17 def at_end?
18   raise NotImplementedError
19 end
backward() click to toggle source

Move backward one position. Returns the source of current_edge. Raises Stream::EndOfStreamException if at_beginning? is true.

   # File lib/stream.rb
36 def backward
37   raise EndOfStreamException if at_beginning?
38 
39   basic_backward
40 end
collect(&mapping) click to toggle source

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.

    # File lib/stream.rb
690 def collect(&mapping)
691   MappedStream.new(self, &mapping)
692 end
concatenate() click to toggle source

Create a Stream::ConcatenatedStream on self, which must be a stream of streams.

    # File lib/stream.rb
696 def concatenate
697   ConcatenatedStream.new self
698 end
concatenate_collected(&mapping) click to toggle source

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]
    # File lib/stream.rb
707 def concatenate_collected(&mapping)
708   collect(&mapping).concatenate
709 end
create_stream() click to toggle source

create_stream is used for each Enumerable to create a stream for it. A Stream as an Enumerable returns itself.

    # File lib/stream.rb
146 def create_stream
147   self
148 end
current() click to toggle source

Returns the element returned by the last call of forward. If at_beginning? is true self is returned.

    # File lib/stream.rb
102 def current
103   at_beginning? ? self : basic_current
104 end
current_edge() click to toggle source

Returns the array [#current,#peek].

    # File lib/stream.rb
113 def current_edge
114   [current, peek]
115 end
each() { |basic_forward until at_end?| ... } click to toggle source

Implements the standard iterator used by module Enumerable, by calling set_to_begin and basic_forward until at_end? is true.

    # File lib/stream.rb
139 def each
140   set_to_begin
141   yield basic_forward until at_end?
142 end
empty?() click to toggle source

Returns true if the stream is empty which is equivalent to at_end? and at_beginning? both being true.

    # File lib/stream.rb
133 def empty?
134   at_end? and at_beginning?
135 end
filtered(&block) click to toggle source

Return a Stream::FilteredStream which iterates over all my elements satisfying the condition specified by the block.

    # File lib/stream.rb
678 def filtered(&block)
679   FilteredStream.new(self, &block)
680 end
first() click to toggle source

Returns the first element of the stream. This is accomplished by calling set_to_begin and forward, which means a state change.

    # File lib/stream.rb
119 def first
120   set_to_begin
121   forward
122 end
forward() click to toggle source

Move forward one position. Returns the target of current_edge. Raises Stream::EndOfStreamException if at_end? is true.

   # File lib/stream.rb
28 def forward
29   raise EndOfStreamException if at_end?
30 
31   basic_forward
32 end
last() click to toggle source

Returns the last element of the stream. This is accomplished by calling set_to_begin and backward, which means a state change.

    # File lib/stream.rb
126 def last
127   set_to_end
128   backward
129 end
modify(&block) click to toggle source

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.

    # File lib/stream.rb
724 def modify(&block)
725   ImplicitStream.new(self, &block)
726 end
move_backward_until() { |element| ... } click to toggle source

Move backward until the boolean block is not false and returns the element found. Returns nil if no object matches.

   # File lib/stream.rb
92 def move_backward_until
93   until at_beginning?
94     element = basic_backward
95     return element if yield(element)
96   end
97   nil
98 end
move_forward_until() { |element| ... } click to toggle source

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.

   # File lib/stream.rb
82 def move_forward_until
83   until at_end?
84     element = basic_forward
85     return element if yield(element)
86   end
87   nil
88 end
peek() click to toggle source

Returns the element returned by the last call of backward. If at_end? is true self is returned.

    # File lib/stream.rb
108 def peek
109   at_end? ? self : basic_peek
110 end
remove_first() click to toggle source

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]
    # File lib/stream.rb
732 def remove_first
733   i = 0
734   filter = filtered { i += 1; i > 1 }
735   filter.modify do |s|
736     s.set_to_begin_proc = proc { filter.set_to_begin; i = 0 }
737   end
738 end
remove_last() click to toggle source

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.

    # File lib/stream.rb
746 def remove_last
747   reverse.remove_first.reverse # I like this one
748 end
reverse() click to toggle source

Create a Stream::ReversedStream wrapper on self.

    # File lib/stream.rb
683 def reverse
684   ReversedStream.new self
685 end
set_to_begin() click to toggle source

Position the stream before its first element, i.e. the next forward will return the first element.

   # File lib/stream.rb
44 def set_to_begin
45   basic_backward until at_beginning?
46 end
set_to_end() click to toggle source

Position the stream behind its last element, i.e. the next backward will return the last element.

   # File lib/stream.rb
50 def set_to_end
51   basic_forward until at_end?
52 end
unwrapped() click to toggle source

A Stream::WrappedStream should return the wrapped stream unwrapped. If the stream is not a wrapper around another stream it simply returns itself.

    # File lib/stream.rb
152 def unwrapped
153   self
154 end

Protected Instance Methods

basic_backward() click to toggle source
   # File lib/stream.rb
60 def basic_backward
61   raise NotImplementedError
62 end
basic_current() click to toggle source
   # File lib/stream.rb
64 def basic_current
65   backward
66   forward
67 end
basic_forward() click to toggle source
   # File lib/stream.rb
56 def basic_forward
57   raise NotImplementedError
58 end
basic_peek() click to toggle source
   # File lib/stream.rb
69 def basic_peek
70   forward
71   backward
72 end