lab42_streams 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
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