lab42_streams 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: bccbce995004e65382114ca3073c25956bfd782d
4
- data.tar.gz: f9e9ca8f5a32e2231bb159edb36054ac0f2d32b6
3
+ metadata.gz: 932f01cab1874c1a2f68148df75733d5ab33561b
4
+ data.tar.gz: 9ec01ace503ab4739c4070cfb9eaacf8ce399f4f
5
5
  SHA512:
6
- metadata.gz: 6b5f37631aa89ad9a7bdec443adc34a3f2f8355247482eaa450cb7e3da159f0742b321060f78032510ef49dba44d3be5a71ca527640ac3952604168e993b6f9e
7
- data.tar.gz: dd4b9c7b4a605103a184f0178218782c88dd040c05372b17a965fa21365aab34c859b4002aac818600487c39528cde2d769dc68fc23256751741f445b3f2be00
6
+ metadata.gz: f8e99130eac0f83c13737636ce55024f13d41e11698ee62370c493f9393b7a6ec78b3d9b047419ffc0b57320c5dfaa36c678b1ce69dcc85a1e815ba9c9c550a5
7
+ data.tar.gz: fd06621f258ec2d9c1f95b7ec1d8cac37c25d18f2b22d21a9e441dee6831efae36624b26432d8841697185f56ebc7a5712fb205ea91c9e292c5ed1f29257d1e6
data/README.md CHANGED
@@ -1,3 +1,11 @@
1
1
  # lab42\_streams
2
2
 
3
- Bringing Streams to the much lazier Ruby 2.0
3
+ Bringing Streams to Ruby
4
+
5
+ An excellent introduction into `Streams` can be found [here](http://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-001-structure-and-interpretation-of-computer-programs-spring-2005/video-lectures/6a-streams-part-1/)
6
+
7
+
8
+
9
+ Please see the [QED](http://rubyworks.github.io/qed/) demos [here](https://github.com/RobertDober/lab42_streams/blob/master/demo)
10
+
11
+ for details.
@@ -0,0 +1,11 @@
1
+ require_relative '../stream'
2
+
3
+ Stream = Lab42::Stream
4
+ EmptyStream = Lab42::Stream::EmptyStream
5
+
6
+ module Kernel
7
+ def iterate *args, &blk
8
+ Stream.iterate( *args, &blk )
9
+ end
10
+ alias_method :stream_by, :iterate
11
+ end # module Kernel
@@ -0,0 +1,17 @@
1
+ module Lab42
2
+ class Stream
3
+ module ClassMethods
4
+ def iterate arg, beh=nil, &blk
5
+ beh = blk.make_behavior beh
6
+ __iterate__ arg, beh
7
+ end
8
+
9
+ private
10
+ def __iterate__ arg, beh
11
+ cons_stream arg do
12
+ __iterate__ beh.( arg ), beh
13
+ end
14
+ end
15
+ end # module ClassMethods
16
+ end # class Stream
17
+ end # module Lab42
File without changes
@@ -1,7 +1,24 @@
1
+ require 'forwarder'
2
+
3
+ require_relative 'empty/enumerable'
4
+
1
5
  module Lab42
2
6
  class Stream
3
7
  class Empty < Stream
4
- # TODO: Implement all self returning methods with Forwarder
8
+ extend Forwarder
9
+ # It is the nature of the EmptyStream instance to return itself for a plethora of methods
10
+ # this can be expressed as follows:
11
+ forward_all :combine, :__combine__,
12
+ :drop, :drop_unitl, :drop_while,
13
+ :flatmap, :__flatmap__, :filter, :__filter__,
14
+ :inject_stream, :__inject__,
15
+ :lazy_take, :lazy_take_until, :lazy_take_while,
16
+ :make_cyclic, :map, :__map__,
17
+ :reduce,
18
+ :segment, :__segment__, :__scan__, :split_by, :split_by_value,
19
+ :zip, :__zip__,
20
+ to_object: :self, as: :itself
21
+
5
22
  def append other
6
23
  raise ArgumentError, "not a stream #{other}" unless self.class.superclass === other
7
24
  # ??? Is the to_stream message a good idea
@@ -11,23 +28,27 @@ module Lab42
11
28
 
12
29
  def empty?; true end
13
30
 
14
- def filter *args, &blk; self end
15
31
 
16
32
  def head; raise StopIteration, "head called on empty stream" end
33
+ def tail; raise StopIteration, "tail called on empty stream" end
34
+
17
35
 
18
- def make_cyclic; self end
19
- def map *args, &blk; self end
20
- # I believe that this definition is sound, although it is an obvious pitfall
21
- # But falling into it once, means understanding streams better, well that is
22
- # my opinion now, we will see what promises the future will bring...
23
- def tail; self end
36
+ def inject *args; args.first end
37
+ alias_method :__inject__, :inject
24
38
 
39
+ # TODO: Move this into lab42/core as Object#itself
40
+ def itself *args, &blk; self end
41
+
42
+ def scan initial, *args, &blk
43
+ [initial]
44
+ end
45
+
46
+ def scan1 *args, &blk
47
+ []
48
+ end
25
49
 
26
- def flatmap *args, &blk; self end
27
- def __flatmap__ a_proc; self end
28
50
 
29
51
  private
30
- def initialize; end
31
52
 
32
53
  def self.new
33
54
  @__instance__ ||= allocate
@@ -37,6 +58,7 @@ module Lab42
37
58
 
38
59
  module ::Kernel
39
60
  def empty_stream; Empty.new end
61
+ Lab42::Stream::EmptyStream = empty_stream
40
62
  end # module ::Kernel
41
63
  end # class Stream
42
64
  end # module Lab42
@@ -1,3 +1,276 @@
1
1
  module Enumerable
2
2
  def to_stream; finite_stream self end
3
3
  end
4
+
5
+ module Lab42
6
+ class Stream
7
+ IllegalState = Class.new RuntimeError
8
+
9
+ module Enumerable
10
+
11
+ def drop_until *bhv, &blk
12
+ bhv = blk.make_behavior( *bhv )
13
+ s = self
14
+ loop do
15
+ return s if bhv.(s.head)
16
+ s = s.tail
17
+ end
18
+ empty_stream
19
+ end
20
+
21
+ # N.B. Not implemented as drop_until( bhv.not )
22
+ # for performance reasons
23
+ def drop_while *bhv, &blk
24
+ bhv = blk.make_behavior( *bhv )
25
+ s = self
26
+ loop do
27
+ return s unless bhv.(s.head)
28
+ s = s.tail
29
+ end
30
+ empty_stream
31
+ end
32
+
33
+ def each
34
+ t = self
35
+ loop do
36
+ yield t.head
37
+ t = t.tail
38
+ end
39
+ end
40
+
41
+ def each_without_loops
42
+ visited = {}
43
+ t = self
44
+ loop do
45
+ h = t.head
46
+ yield h
47
+ visited[ t.object_id ] = true
48
+ t = t.tail
49
+ return if visited[t.object_id]
50
+ end
51
+ end
52
+
53
+ def force_all cache={}
54
+ x = []
55
+ each_without_loops do | ele |
56
+ if self.class === ele
57
+ if ! cache[ele.object_id]
58
+ cache[ele.object_id] = true
59
+ x << ele.force_all( cache )
60
+ end
61
+ else
62
+ x << ele
63
+ end
64
+ end
65
+ x
66
+ end
67
+
68
+ def lazy_take n=1
69
+ raise ArgumentError, "need a non negative Fixnum" if !(Fixnum === n) || n < 0
70
+ __lazy_take__ n
71
+ end
72
+
73
+ def __lazy_take__ n
74
+ return empty_stream if n.zero?
75
+ cons_stream( head ){ tail.__lazy_take__ n.pred }
76
+ end
77
+
78
+ def lazy_take_until *bhv, &blk
79
+ bhv = blk.make_behavior( *bhv )
80
+ __lazy_take_until__ bhv
81
+ end
82
+
83
+ def __lazy_take_until__ bhv
84
+ return empty_stream if bhv.(head)
85
+ cons_stream( head ){
86
+ tail.__lazy_take_until__ bhv
87
+ }
88
+ end
89
+
90
+ def lazy_take_while *bhv, &blk
91
+ bhv = blk.make_behavior( *bhv )
92
+ __lazy_take_while__ bhv
93
+ end
94
+
95
+ def __lazy_take_while__ bhv
96
+ return empty_stream unless bhv.(head)
97
+ cons_stream( head ){
98
+ tail.__lazy_take_while__ bhv
99
+ }
100
+ end
101
+
102
+ def reduce red=nil, &reducer
103
+ red = reducer.make_behavior( red )
104
+ tail.__inject__ head, red
105
+ end
106
+
107
+ def inject agg, *red, &reducer
108
+ __inject__ agg, reducer.make_behavior( *red )
109
+ end
110
+
111
+ def filter *args, &blk
112
+ __filter__ blk.make_behavior( *args )
113
+ end
114
+
115
+ def reject *args, &blk
116
+ __filter__ blk.make_behavior( *args ).not
117
+ end
118
+
119
+ def flatmap *args, &blk
120
+ __flatmap__ blk.make_behavior( *args )
121
+ end
122
+
123
+ def __flatmap__ a_proc
124
+ # require 'pry'
125
+ # binding.pry
126
+ hh = a_proc.( head )
127
+ if hh.empty?
128
+ tail.__flatmap__ a_proc
129
+ else
130
+ cons_stream( hh.head ){ hh.tail + tail.__flatmap__( a_proc ) }
131
+ end
132
+ end
133
+
134
+ def flatmap_with_each *args, &blk
135
+ __flatmap_with_each__ blk.make_behavior( *args )
136
+ end
137
+
138
+ def __flatmap_with_each__ a_proc, rest_of_enum = []
139
+ # Process expanded values
140
+ return cons_stream( rest_of_enum.first ){ __flatmap_with_each__ a_proc, rest_of_enum.drop( 1 ) } unless
141
+ rest_of_enum.empty?
142
+
143
+ # Map a scalar value
144
+ hh = a_proc.( head )
145
+ return cons_stream( hh ){ tail.__flatmap_with_each__ a_proc } unless
146
+ hh.respond_to? :each
147
+
148
+ # Start a new expansion...
149
+ # ... consider an empty expansion
150
+ return tail.__flatmap__ a_proc if hh.empty?
151
+ # ... expand values
152
+ cons_stream( hh.first ){ tail.__flatmap_with_each__( a_proc, hh.drop( 1 ) ) }
153
+ end
154
+
155
+
156
+ def scan initial, *args, &blk
157
+ cons_stream initial do
158
+ __scan__ initial, blk.make_behavior( *args )
159
+ end.tap{ |r|
160
+ # require 'pry'
161
+ # binding.pry
162
+ }
163
+ end
164
+
165
+ def scan1 *args, &blk
166
+ tail.scan( head, *args, &blk )
167
+ end
168
+
169
+ def __scan__ initial, beh
170
+ h = beh.(initial, head)
171
+ cons_stream( h ){ tail.__scan__ h, beh }
172
+ end
173
+
174
+ def take_until *bhv, &blk
175
+ bhv = blk.make_behavior( *bhv )
176
+ x = []
177
+ each do | ele |
178
+ return x if bhv.( ele )
179
+ x << ele
180
+ end
181
+ x
182
+ end
183
+ def take_while *bhv, &blk
184
+ bhv = blk.make_behavior( *bhv )
185
+ x = []
186
+ each do | ele |
187
+ return x unless bhv.( ele )
188
+ x << ele
189
+ end
190
+ x
191
+ end
192
+
193
+ def to_a
194
+ take_while :true
195
+ end
196
+ alias_method :entries, :to_a
197
+
198
+ def make_cyclic
199
+ cons_stream( head ){
200
+ tail.append( make_cyclic )
201
+ }
202
+ end
203
+
204
+ def map *args, &blk
205
+ # TODO: Get this check and a factory to create a proc for this into core/fn
206
+ raise ArgumentError, "use either a block or arguments" if args.empty? && !blk || !args.empty? && blk
207
+ __map__ blk.make_behavior( *args )
208
+ end
209
+
210
+ def __map__ prc
211
+ cons_stream( prc.(head) ){ tail.__map__ prc }
212
+ end
213
+
214
+
215
+ def reduce_while cond, red=nil, &reducer
216
+ red ||= reducer
217
+ tail.__inject_while__ head, cond, red
218
+ end
219
+
220
+ def take n=1
221
+ raise ArgumentError, "need a non negative Fixnum" if !(Fixnum === n) || n < 0
222
+ x = []
223
+ each do | ele |
224
+ return x if n.zero?
225
+ n -= 1
226
+ x << ele
227
+ end
228
+ x
229
+ end
230
+
231
+ def zip *other_streamables
232
+ streams = other_streamables.map{ |s|
233
+ self.class === s ? s : s.to_stream
234
+ }
235
+ __zip__ streams
236
+ end
237
+
238
+ def zip_as_ary *other_streamables
239
+ zip( *other_streamables )
240
+ .map( &:entries )
241
+ end
242
+
243
+ def __zip__ streams
244
+ cons_stream( [head] + streams.map(:head) ){
245
+ tail.__zip__ streams.map(:tail)
246
+ }
247
+ end
248
+
249
+ def __filter__ a_proc
250
+ if a_proc.( head )
251
+ cons_stream( head ){ tail.__filter__ a_proc }
252
+ else
253
+ tail.__filter__ a_proc
254
+ end
255
+ end
256
+
257
+ def __inject__ agg, a_proc
258
+ new_agg = a_proc.(agg, head)
259
+ tail.__inject__ new_agg, a_proc
260
+ end
261
+
262
+ def __inject_while__ ival, cond, red
263
+ raise ConstraintError unless cond.(ival)
264
+ s = self
265
+ loop do
266
+ new_val = red.(ival, s.head)
267
+ return ival unless cond.(new_val)
268
+ ival = new_val
269
+ s = s.tail
270
+ return ival if s.empty?
271
+ end
272
+ end
273
+ end # module Enumerable
274
+ include Enumerable
275
+ end # class Stream
276
+ end # module Lab42
@@ -0,0 +1,33 @@
1
+ module Lab42
2
+ class Stream
3
+ module HigherOrder
4
+ def combine *streams_and_op, &operation
5
+ op = streams_and_op.pop unless self.class === streams_and_op.last
6
+ op = operation.make_behavior op
7
+ # TODO: Decide what to do if op.arity and streams_and_op.size.succ do not match????
8
+ __combine__( op, *streams_and_op )
9
+ end
10
+
11
+ def __combine__ op, *streams
12
+ # TODO: Decide if we can continue if one of the streams is empty iff op.arity < 0
13
+ # for now no!
14
+ return empty_stream if streams.any?( &:empty? )
15
+ values = streams.map( &:head )
16
+ new_head = op.(head, *values)
17
+ cons_stream( new_head ){
18
+ tail.__combine__( op, *streams.map( &:tail ) )
19
+ }
20
+ end
21
+
22
+ def split_into n
23
+ indexed = with_index
24
+ n.times.map do | i |
25
+ indexed
26
+ .filter{ |e, idx| idx % n == i }
27
+ .map( :first )
28
+ end
29
+ end
30
+ end # module HigherOrder
31
+ include HigherOrder
32
+ end # class Stream
33
+ end # module Lab42
@@ -0,0 +1,7 @@
1
+
2
+ module Kernel
3
+ def true; true end
4
+ def false; false end
5
+ def nil; nil end
6
+ def self; self end
7
+ end # module Kernel
@@ -6,12 +6,8 @@ module Kernel
6
6
  end
7
7
  end
8
8
 
9
- def combine_streams s1, s2, op=nil, &operation
10
- return empty_stream if s1.empty? || s2.empty?
11
- op ||= operation
12
- cons_stream op.(s1.head, s2.head) do
13
- combine_streams( s1.tail, s2.tail, op)
14
- end
9
+ def combine_streams stream, *streams_and_ops, &operation
10
+ stream.combine( *streams_and_ops, &operation )
15
11
  end
16
12
 
17
13
  def cons_stream head, &tail
@@ -24,7 +20,7 @@ module Kernel
24
20
 
25
21
  def cyclic_stream *args
26
22
  args = args.first if
27
- args.size == 1 && Enumerable === args.first
23
+ args.size == 1 && Enumerable === args.first
28
24
 
29
25
  finite_stream( args ).make_cyclic
30
26
  end
@@ -50,16 +46,17 @@ module Kernel
50
46
  end
51
47
  end
52
48
 
53
- def stream_by *args, &blk
49
+ def iterate *args, &blk
54
50
  if blk
55
- cons_stream(*args){ stream_by( blk.(*args), &blk ) }
51
+ cons_stream(*args){ iterate( blk.(*args), &blk ) }
56
52
  else
57
53
  rest = args.drop 1
58
54
  if Method === rest.first
59
- cons_stream( args.first ){ stream_by( rest.first.(*([args.first] + rest.drop(1))), *rest ) }
55
+ cons_stream( args.first ){ iterate( rest.first.(*([args.first] + rest.drop(1))), *rest ) }
60
56
  else
61
- cons_stream( args.first ){ stream_by( sendmsg(*rest).(args.first), *rest ) }
62
- end
57
+ cons_stream( args.first ){ iterate( sendmsg(*rest).(args.first), *rest ) }
58
+ end
63
59
  end
64
60
  end
61
+ alias_method :stream_by, :iterate
65
62
  end
@@ -11,4 +11,29 @@ class Proc
11
11
  end
12
12
  }
13
13
  end
14
+
15
+ # TODO: Use this from core/fn as soon as available
16
+ def make_behavior *args
17
+ raise ArgumentError, "cannot specify behavior with block and args: #{args.inspect}" unless args.compact.empty?
18
+ self
19
+ end
20
+
21
+ def not
22
+ -> (*args, &blk) {
23
+ ! self.(*args, &blk)
24
+ }
25
+ end
26
+ end
27
+
28
+ class NilClass
29
+ # TODO: Use this from core/fn as soon as available
30
+ def make_behavior *args
31
+ return args.first if args.size == 1 && args.first.respond_to?( :call )
32
+
33
+ return ->(*a){
34
+ args.first(*(args.drop(1)+a))
35
+ } if args.first.respond_to?( :call )
36
+
37
+ sendmsg( *args )
38
+ end
14
39
  end
@@ -0,0 +1,27 @@
1
+ module Lab42
2
+ class Stream
3
+ module Utility
4
+
5
+ def segment *args, &blk
6
+ __segment__ blk.make_behavior( *args )
7
+ end
8
+
9
+ def __segment__ beh
10
+ if beh.( head )
11
+ cons_stream( cons_stream( head ){ tail.lazy_take_until beh } ){
12
+ tail.drop_until( beh ).__segment__ beh
13
+ }
14
+ else
15
+ cons_stream( lazy_take_until beh ){
16
+ tail.drop_until( beh ).__segment__ beh
17
+ }
18
+ end
19
+ end
20
+
21
+ def with_index start=0
22
+ zip_as_ary iterate( start, :succ )
23
+ end
24
+ end # module Utility
25
+ include Utility
26
+ end # class Stream
27
+ end # module Lab42
@@ -1,5 +1,5 @@
1
1
  module Lab42
2
2
  class Stream
3
- Version = "0.1.0"
3
+ Version = "0.1.1"
4
4
  end # class Stream
5
5
  end # module Lab42
data/lib/lab42/stream.rb CHANGED
@@ -1,16 +1,25 @@
1
- require 'lab42/stream/empty'
2
- require 'lab42/stream/delayed'
3
- require 'lab42/stream/kernel'
4
- require 'lab42/stream/array'
5
- require 'lab42/stream/enumerable'
6
- require 'lab42/stream/hash'
7
- require 'lab42/stream/proc'
1
+
2
+ require_relative './stream/empty'
3
+ require_relative './stream/delayed'
4
+ require_relative './stream/kernel'
5
+ require_relative './stream/array'
6
+ require_relative './stream/enumerable'
7
+ require_relative './stream/higher_order'
8
+ require_relative './stream/hash'
9
+ require_relative './stream/proc'
10
+ require_relative './stream/class_methods'
11
+ require_relative './stream/utility'
12
+
13
+ # TODO: This should rather be implemented in lab_42/core/fn
14
+ require_relative './stream/kernel/extensions'
8
15
 
9
16
  module Lab42
10
17
  class Stream
18
+ extend ClassMethods
19
+
11
20
  ConstraintError = Class.new RuntimeError
12
- include Enumerable
13
21
  attr_reader :head, :promise
22
+ alias_method :first, :head
14
23
 
15
24
  def append other
16
25
  raise ArgumentError, "not a stream #{other}" unless self.class === other
@@ -18,6 +27,13 @@ module Lab42
18
27
  end
19
28
  alias_method :+, :append
20
29
 
30
+
31
+ def combine_streams *args, &operation
32
+ op = args.shift unless self.class === args.first
33
+ raise ArgumentError, "Missing stream parameters" if args.empty?
34
+ __combine_streams__ operation.make_behavior( op ), args
35
+ end
36
+
21
37
  def drop n = 1
22
38
  raise ArgumentError, "not a non negative number" if n < 0
23
39
  t = self
@@ -28,102 +44,33 @@ module Lab42
28
44
  end
29
45
  end
30
46
 
31
- def each
32
- t = self
33
- loop do
34
- yield t.head
35
- t = t.tail
36
- end
37
- end
38
-
39
47
  def empty?; false end
40
48
 
41
- def filter *args, &blk
42
- # TODO: Get this check and a factory to create a proc for this into core
43
- raise ArgumentError, "use either a block or arguments" if args.empty? && !blk || !args.empty? && blk
44
- filter_by_proc mk_proc( blk || args )
45
- end
46
-
47
- def filter_by_proc prc
48
- if prc.(head)
49
- cons_stream(head){ tail.filter_by_proc prc }
50
- else
51
- # TODO: Replace this with Delayed Stream (1 off)
52
- tail.filter_by_proc prc
53
- end
54
- end
55
-
56
- def flatmap *args, &blk
57
- if args.empty?
58
- __flatmap__ blk
59
- elsif args.size == 1 && args.first.respond_to?( :call )
60
- __flatmap__ args.first
61
- else
62
- __flatmap__ sendmsg(*args)
63
- end
64
- end
65
-
66
- def __inject_while__ ival, cond, red
67
- raise ConstraintError unless cond.(ival)
68
- s = self
69
- loop do
70
- new_val = red.(ival, s.head)
71
- return ival unless cond.(new_val)
72
- ival = new_val
73
- s = s.tail
74
- return ival if s.empty?
75
- end
76
- end
77
-
78
- def make_cyclic
79
- cons_stream( head ){
80
- tail.append( make_cyclic )
81
- }
82
- end
83
-
84
- def map *args, &blk
85
- # TODO: Get this check and a factory to create a proc for this into core/fn
86
- raise ArgumentError, "use either a block or arguments" if args.empty? && !blk || !args.empty? && blk
87
- transform_by_proc mk_proc( blk || args )
88
- end
89
-
90
- def reduce_while cond, red=nil, &reducer
91
- red ||= reducer
92
- tail.__inject_while__ head, cond, red
93
- end
94
-
95
49
  def tail
96
50
  promise.()
97
51
  end
98
52
 
99
53
  def to_stream; self end
100
54
 
101
- def transform_by_proc prc
102
- cons_stream( prc.(head) ){ tail.transform_by_proc prc }
103
- end
55
+ def __combine_streams__ op, args
56
+ return empty_stream if args.any?(&sendmsg(:empty?))
104
57
 
105
- def __flatmap__ a_proc
106
- hh = a_proc.( head )
107
- if hh.empty?
108
- tail.__flatmap__ a_proc
109
- else
110
- cons_stream( hh.head ){ hh.tail + tail.__flatmap__( a_proc ) }
111
- end
58
+ new_head = op.(head, *args.map(&sendmsg(:head)))
59
+ cons_stream( new_head ){ tail.__combine_streams__(op, args.map(&sendmsg(:tail))) }
112
60
  end
113
61
 
114
62
  private
115
63
  def initialize h, t=nil, &tail
116
- @head = h
117
- @promise = ( t || tail ).memoized
64
+ @head = h
65
+ @promise = ( t || tail ).memoized
118
66
  end
119
67
 
120
- # TODO: Use this from core/fn as soon as available
121
- def mk_proc args
122
- return args if Proc === args
123
- raise ArgumentError, "neither a Proc nor an array of args for Kernel#sendmsg" unless Array === args
124
- return args.first if Proc === args.first || Method === args.first
125
- sendmsg(*args)
126
- end
68
+ # def mk_proc args
69
+ # return args if Proc === args
70
+ # raise ArgumentError, "neither a Proc nor an array of args for Kernel#sendmsg" unless Array === args
71
+ # return args.first if Proc === args.first || Method === args.first
72
+ # sendmsg(*args)
73
+ # end
127
74
 
128
75
  end # class Stream
129
76
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lab42_streams
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Robert Dober
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-10-19 00:00:00.000000000 Z
11
+ date: 2014-07-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: forwarder2
@@ -52,37 +52,99 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: 0.9.12
55
+ - !ruby/object:Gem::Dependency
56
+ name: pry-nav
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '0.2'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '0.2'
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: rspec
57
71
  requirement: !ruby/object:Gem::Requirement
58
72
  requirements:
59
73
  - - "~>"
60
74
  - !ruby/object:Gem::Version
61
- version: 2.13.0
75
+ version: 2.14.0
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 2.14.0
83
+ - !ruby/object:Gem::Dependency
84
+ name: qed
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '2.9'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '2.9'
97
+ - !ruby/object:Gem::Dependency
98
+ name: ae
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '1.8'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '1.8'
111
+ - !ruby/object:Gem::Dependency
112
+ name: byebug
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '3.1'
62
118
  type: :development
63
119
  prerelease: false
64
120
  version_requirements: !ruby/object:Gem::Requirement
65
121
  requirements:
66
122
  - - "~>"
67
123
  - !ruby/object:Gem::Version
68
- version: 2.13.0
124
+ version: '3.1'
69
125
  description: Lazy Evaluation, Streams, Enumerator#Lazy
70
126
  email: robert.dober@gmail.com
71
127
  executables: []
72
128
  extensions: []
73
129
  extra_rdoc_files: []
74
130
  files:
131
+ - LICENSE
132
+ - README.md
75
133
  - lib/lab42/stream.rb
76
134
  - lib/lab42/stream/array.rb
77
- - lib/lab42/stream/version.rb
135
+ - lib/lab42/stream/auto_import.rb
136
+ - lib/lab42/stream/class_methods.rb
78
137
  - lib/lab42/stream/delayed.rb
79
- - lib/lab42/stream/hash.rb
80
138
  - lib/lab42/stream/empty.rb
81
- - lib/lab42/stream/proc.rb
82
- - lib/lab42/stream/kernel.rb
139
+ - lib/lab42/stream/empty/enumerable.rb
83
140
  - lib/lab42/stream/enumerable.rb
84
- - LICENSE
85
- - README.md
141
+ - lib/lab42/stream/hash.rb
142
+ - lib/lab42/stream/higher_order.rb
143
+ - lib/lab42/stream/kernel.rb
144
+ - lib/lab42/stream/kernel/extensions.rb
145
+ - lib/lab42/stream/proc.rb
146
+ - lib/lab42/stream/utility.rb
147
+ - lib/lab42/stream/version.rb
86
148
  homepage: https://github.com/RobertDober/lab42_streams
87
149
  licenses:
88
150
  - MIT
@@ -103,7 +165,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
103
165
  version: '0'
104
166
  requirements: []
105
167
  rubyforge_project:
106
- rubygems_version: 2.1.5
168
+ rubygems_version: 2.2.2
107
169
  signing_key:
108
170
  specification_version: 4
109
171
  summary: Streams for Ruby 2.0