abstractivator 0.3.1 → 0.4.0
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:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fde467c865fb41d53a7c256fd150d5c2f3bbb947
|
4
|
+
data.tar.gz: 97e60569e7a56d45c24bafaf345f22856eb3b8c7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1671b95d9e955f6ec00fc93972b6cea6b18311a0c0be80880010394c26fd3563c42d32228ceb8c500d463c4d95b567e4f48b03a88fdfea76d476ddd3b76f2535
|
7
|
+
data.tar.gz: 5655785a88eb97cd688bfbecf4923ce4f3db7074425e470c33d52143207d72681a49980cba7a44db07bfd592b37fa8a2abacab4463681403567776f83eba7450
|
@@ -0,0 +1,33 @@
|
|
1
|
+
class Enumerator
|
2
|
+
# @param state [Object] The initial state
|
3
|
+
# @yieldparam state [Object] the current state
|
4
|
+
# @yieldreturn [Array] a 2-element array containing the next value and the next state
|
5
|
+
def self.unfold(state)
|
6
|
+
raise 'block is required' unless block_given?
|
7
|
+
Enumerator.new do |y|
|
8
|
+
unless state.nil?
|
9
|
+
loop do
|
10
|
+
next_value, state = yield(state)
|
11
|
+
break if state.nil?
|
12
|
+
y << next_value
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
attr_accessor :__memo__, :__memo_instance__
|
19
|
+
|
20
|
+
def memoized
|
21
|
+
@__memo_instance__ ||= self.dup
|
22
|
+
inner = __memo_instance__
|
23
|
+
inner.__memo__ ||= []
|
24
|
+
Enumerator.new do |y|
|
25
|
+
i = 0
|
26
|
+
loop do
|
27
|
+
inner.__memo__ << inner.next while inner.__memo__.size <= i
|
28
|
+
y << inner.__memo__[i]
|
29
|
+
i += 1
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'rspec'
|
2
|
+
require 'abstractivator/enumerator_ext'
|
3
|
+
|
4
|
+
describe 'Enumerator' do
|
5
|
+
describe '::unfold' do
|
6
|
+
it 'generates an enumerator based on state changes over time' do
|
7
|
+
naturals = Enumerator.unfold(1) { |nxt| [nxt, nxt + 1] }
|
8
|
+
expect(naturals.take(5)).to eql [1,2,3,4,5]
|
9
|
+
end
|
10
|
+
it 'stops when state becomes nil' do
|
11
|
+
xs = [1,2,3]
|
12
|
+
tails = Enumerator.unfold(xs) { |xs| xs.empty? ? [nil, nil] : [xs, xs.drop(1)] }
|
13
|
+
expect(tails.to_a).to eql [[1,2,3],[2,3],[3]]
|
14
|
+
end
|
15
|
+
it 'returns an empty array if the initial state is nil' do
|
16
|
+
expect(Enumerator.unfold(nil){}.to_a).to eql []
|
17
|
+
end
|
18
|
+
it 'raises an error if no block is provided' do
|
19
|
+
expect{Enumerator.unfold(nil)}.to raise_error
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe '#memoized' do
|
24
|
+
it 'returns a memoized version of the enumerator' do
|
25
|
+
work = []
|
26
|
+
naturals = Enumerator.new do |y|
|
27
|
+
i = 1
|
28
|
+
loop do
|
29
|
+
# puts "calculating #{i}"
|
30
|
+
work << i
|
31
|
+
y << i
|
32
|
+
i += 1
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
wrapped = naturals.memoized
|
37
|
+
expect(wrapped.take(3)).to eql [1,2,3]
|
38
|
+
expect(work).to eql [1,2,3]
|
39
|
+
|
40
|
+
# reenumerating doesn't do additional work
|
41
|
+
expect(wrapped.take(3)).to eql [1,2,3]
|
42
|
+
expect(work).to eql [1,2,3]
|
43
|
+
|
44
|
+
# enumerating more does the minimum amount of work
|
45
|
+
expect(wrapped.take(5)).to eql [1,2,3,4,5]
|
46
|
+
expect(work).to eql [1,2,3,4,5]
|
47
|
+
|
48
|
+
# subsequent calls share the memo
|
49
|
+
wrapped2 = naturals.memoized
|
50
|
+
expect(wrapped2.take(5)).to eql [1,2,3,4,5]
|
51
|
+
expect(work).to eql [1,2,3,4,5]
|
52
|
+
|
53
|
+
# wrapped instances are independent
|
54
|
+
a = naturals.memoized
|
55
|
+
b = naturals.memoized
|
56
|
+
expect(a.next).to eql 1
|
57
|
+
expect(a.next).to eql 2
|
58
|
+
expect(b.next).to eql 1
|
59
|
+
expect(a.next).to eql 3
|
60
|
+
expect(b.next).to eql 2
|
61
|
+
|
62
|
+
# wrapped enumerator is unaffected
|
63
|
+
expect(naturals.next).to eql 1
|
64
|
+
expect(naturals.take(3)).to eql [1,2,3]
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'rspec'
|
2
|
+
require 'abstractivator/numbers'
|
3
|
+
|
4
|
+
describe Numbers do
|
5
|
+
describe '::from' do
|
6
|
+
it 'returns a stream of numbers starting at the given number' do
|
7
|
+
expect(Numbers.from(1).take(3)).to eql [1,2,3]
|
8
|
+
end
|
9
|
+
it 'accepts an interval' do
|
10
|
+
expect(Numbers.from(0, 5).take(3)).to eql [0,5,10]
|
11
|
+
expect(Numbers.from(3, -1).take(3)).to eql [3,2,1]
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: abstractivator
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Peter Winton
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-11-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -114,8 +114,10 @@ files:
|
|
114
114
|
- lib/abstractivator/cons.rb
|
115
115
|
- lib/abstractivator/enum.rb
|
116
116
|
- lib/abstractivator/enumerable_ext.rb
|
117
|
+
- lib/abstractivator/enumerator_ext.rb
|
117
118
|
- lib/abstractivator/event.rb
|
118
119
|
- lib/abstractivator/fiber_defer.rb
|
120
|
+
- lib/abstractivator/numbers.rb
|
119
121
|
- lib/abstractivator/proc_ext.rb
|
120
122
|
- lib/abstractivator/schedule.rb
|
121
123
|
- lib/abstractivator/schedule/schedule.rb
|
@@ -132,8 +134,10 @@ files:
|
|
132
134
|
- spec/lib/abstractivator/cons_spec.rb
|
133
135
|
- spec/lib/abstractivator/enum_spec.rb
|
134
136
|
- spec/lib/abstractivator/enumerable_ext_spec.rb
|
137
|
+
- spec/lib/abstractivator/enumerator_ext_spec.rb
|
135
138
|
- spec/lib/abstractivator/event_spec.rb
|
136
139
|
- spec/lib/abstractivator/fiber_defer_spec.rb
|
140
|
+
- spec/lib/abstractivator/numbers_spec.rb
|
137
141
|
- spec/lib/abstractivator/proc_ext_spec.rb
|
138
142
|
- spec/lib/abstractivator/schedule/em_util.rb
|
139
143
|
- spec/lib/abstractivator/schedule/schedule_runner_spec.rb
|
@@ -172,8 +176,10 @@ test_files:
|
|
172
176
|
- spec/lib/abstractivator/cons_spec.rb
|
173
177
|
- spec/lib/abstractivator/enum_spec.rb
|
174
178
|
- spec/lib/abstractivator/enumerable_ext_spec.rb
|
179
|
+
- spec/lib/abstractivator/enumerator_ext_spec.rb
|
175
180
|
- spec/lib/abstractivator/event_spec.rb
|
176
181
|
- spec/lib/abstractivator/fiber_defer_spec.rb
|
182
|
+
- spec/lib/abstractivator/numbers_spec.rb
|
177
183
|
- spec/lib/abstractivator/proc_ext_spec.rb
|
178
184
|
- spec/lib/abstractivator/schedule/em_util.rb
|
179
185
|
- spec/lib/abstractivator/schedule/schedule_runner_spec.rb
|