transducers 0.4.94

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.
@@ -0,0 +1,21 @@
1
+ # Copyright 2014 Cognitect. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS-IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ $LOAD_PATH << 'lib'
16
+ require 'transducers'
17
+
18
+ RSpec.configure do |config|
19
+ config.filter_run :focus
20
+ config.run_all_when_everything_filtered = true
21
+ end
@@ -0,0 +1,49 @@
1
+ # Copyright 2014 Cognitect. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS-IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require 'spec_helper'
16
+
17
+ RSpec.describe Transducers::Reducer do
18
+ Reducer = Transducers::Reducer
19
+
20
+ example do
21
+ r = Reducer.new(0, :+)
22
+ expect(r.init).to eq(0)
23
+ expect(r.complete(1)).to eq(1)
24
+ expect(r.step(3,7)).to eq(10)
25
+ end
26
+
27
+ example do
28
+ r = Reducer.new(0) {|r,i| r+i}
29
+ expect(r.init).to eq(0)
30
+ expect(r.complete(1)).to eq(1)
31
+ expect(r.step(3,7)).to eq(10)
32
+ end
33
+
34
+ example do
35
+ init = Class.new do
36
+ attr_reader :val
37
+ def initialize
38
+ @val = []
39
+ end
40
+
41
+ def foo(v)
42
+ @val << v
43
+ self
44
+ end
45
+ end.new
46
+ result = Transducers.transduce(Transducers.map {|n|n+1}, :foo, init, [1,2,3])
47
+ expect(result.val).to eq([2,3,4])
48
+ end
49
+ end
@@ -0,0 +1,286 @@
1
+ # Copyright 2014 Cognitect. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS-IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require 'spec_helper'
16
+
17
+ RSpec.describe Transducers do
18
+ alias orig_expect expect
19
+
20
+ T = Transducers
21
+
22
+ def expect(expected, &actual)
23
+ orig_expect(actual.call).to eq(expected)
24
+ end
25
+
26
+ it "creates a map transducer with a block" do
27
+ expect([2,3,4]) do
28
+ T.transduce(T.map {|n| n + 1}, :<<, [], [1,2,3])
29
+ end
30
+ end
31
+
32
+ it "creates a map transducer with a Symbol" do
33
+ expect([2,3,4]) do
34
+ T.transduce(T.map(:succ), :<<, [], [1,2,3])
35
+ end
36
+ end
37
+
38
+ it "creates a map transducer with an object that implements call" do
39
+ inc = Class.new do
40
+ def call(n) n + 1 end
41
+ end.new
42
+
43
+ expect([2,3,4]) do
44
+ T.transduce(T.map(inc), :<<, [], [1,2,3])
45
+ end
46
+ end
47
+
48
+ it "creates a filter transducer with a Symbol" do
49
+ expect([2,4]) do
50
+ T.transduce(T.filter(:even?), :<<, [], [1,2,3,4,5])
51
+ end
52
+ end
53
+
54
+ it "creates a filter transducer with a Block" do
55
+ expect([2,4]) do
56
+ T.transduce(T.filter {|x| x.even?}, :<<, [], [1,2,3,4,5])
57
+ end
58
+ end
59
+
60
+ it "creates a filter transducer with an object that implements call" do
61
+ expect([2,4]) do
62
+ even = Class.new do
63
+ def call(n) n.even? end
64
+ end.new
65
+ T.transduce(T.filter(even), :<<, [], [1,2,3,4,5])
66
+ end
67
+ end
68
+
69
+ it "creates a remove transducer with a Symbol" do
70
+ expect([1,3,5]) do
71
+ T.transduce(T.remove(:even?), :<<, [], [1,2,3,4,5])
72
+ end
73
+ end
74
+
75
+ it "creates a remove transducer with a Block" do
76
+ expect([1,3,5]) do
77
+ T.transduce(T.remove {|x| x.even?}, :<<, [], [1,2,3,4,5])
78
+ end
79
+ end
80
+
81
+ it "creates a remove transducer with an object that implements call" do
82
+ expect([1,3,5]) do
83
+ even = Class.new do
84
+ def call(n) n.even? end
85
+ end.new
86
+ T.transduce(T.remove(even), :<<, [], [1,2,3,4,5])
87
+ end
88
+ end
89
+
90
+ it "creates a take transducer" do
91
+ expect([1,2,3,4,5]) do
92
+ T.transduce(T.take(5), :<<, [], 1.upto(20))
93
+ end
94
+ end
95
+
96
+ it "creates a take_while transducer" do
97
+ expect([1,2,3,4,5]) do
98
+ T.transduce(T.take_while {|n| n < 6}, :<<, [], 1.upto(20))
99
+ end
100
+
101
+ expect([1,1,1]) do
102
+ T.transduce(T.take_while {|n| n.odd?}, :<<, [], [1,1,1,2,3])
103
+ end
104
+ end
105
+
106
+ it "creates a take_nth transducer" do
107
+ expect([3,6,9,12]) do
108
+ T.transduce(T.take_nth(3), :<<, [], 1..12)
109
+ end
110
+
111
+ expect([3,6,9,12]) do
112
+ T.transduce(T.take_nth(3), :<<, [], 1..13)
113
+ end
114
+
115
+ expect([3,6,9,12]) do
116
+ T.transduce(T.take_nth(3), :<<, [], 1..14)
117
+ end
118
+ end
119
+
120
+ it "creates a drop transducer" do
121
+ expect([16,17,18,19,20]) do
122
+ T.transduce(T.drop(15), :<<, [], 1.upto(20))
123
+ end
124
+ end
125
+
126
+ it "creates a drop_while transducer" do
127
+ expect((6..20).to_a) do
128
+ T.transduce(T.drop_while {|n| n < 6}, :<<, [], 1.upto(20))
129
+ end
130
+
131
+ expect([2,3]) do
132
+ T.transduce(T.drop_while {|n| n.odd?}, :<<, [], [1,1,1,2,3])
133
+ end
134
+ end
135
+
136
+ it "creates a replace transducer" do
137
+ expect([:zeroth, :second, :fourth, :zeroth]) do
138
+ T.transduce(T.replace([:zeroth, :first, :second, :third, :fourth]), :<<, [], [0, 2, 4, 0])
139
+ end
140
+
141
+ expect([:codes, :zero, :one, :two, :zero]) do
142
+ T.transduce(T.replace({0 => :zero, 1 => :one, 2 => :two}), :<<, [], [:codes, 0, 1, 2, 0])
143
+ end
144
+ end
145
+
146
+ it "creates a keep transducer" do
147
+ expect([false, true, false, true, false]) do
148
+ T.transduce(T.keep(:even?), :<<, [], 1..5)
149
+ end
150
+
151
+ expect([1,3,5,7,9]) do
152
+ T.transduce(T.keep {|n| n if n.odd?}, :<<, [], 0..9)
153
+ end
154
+ end
155
+
156
+ it "creates a keep_indexed transducer" do
157
+ expect([:b, :d]) do
158
+ T.transduce(T.keep_indexed {|i,v| v if i.odd?}, :<<, [], [:a, :b, :c, :d, :e])
159
+ end
160
+
161
+ expect([2,4,5]) do
162
+ T.transduce(T.keep_indexed {|i,v| i if v > 0}, :<<, [], [-9, 0, 29, -7, 45, 3, -8])
163
+ end
164
+
165
+ expect([2,4,5]) do
166
+ handler = Class.new do
167
+ def call(i,v)
168
+ i if v > 0
169
+ end
170
+ end
171
+ T.transduce(T.keep_indexed(handler.new), :<<, [], [-9, 0, 29, -7, 45, 3, -8])
172
+ end
173
+ end
174
+
175
+ it "creates a dedupe transducer" do
176
+ expect([1,2,1,3,4,1,5]) do
177
+ T.transduce(T.dedupe, :<<, [], [1,2,2,1,1,1,3,4,4,1,1,5])
178
+ end
179
+ end
180
+
181
+ it "creates a cat transducer" do
182
+ expect([1,2,3,4]) do
183
+ T.transduce(T.cat, :<<, [], [[1,2],[3,4]])
184
+ end
185
+ end
186
+
187
+ it "creates a mapcat transducer with an object" do
188
+ range_builder = Class.new do
189
+ def call(n) 0...n; end
190
+ end.new
191
+
192
+ expect([0,0,1,0,1,2]) do
193
+ T.transduce(T.mapcat(range_builder), :<<, [], [1,2,3])
194
+ end
195
+ end
196
+
197
+ it "creates a mapcat transducer with a block" do
198
+ expect([0,0,1,0,1,2]) do
199
+ T.transduce(T.mapcat {|n| 0...n}, :<<, [], [1,2,3])
200
+ end
201
+ end
202
+
203
+ it "creates a partition_by transducer" do
204
+ expect([[1,2],[3],[4,5]]) do
205
+ T.transduce(T.partition_by {|n| n == 3}, :<<, [], 1..5)
206
+ end
207
+
208
+ expect([["A"],["B","B"],["A"]]) do
209
+ T.transduce(T.partition_by {|n|n}, :<<, [], "ABBA")
210
+ end
211
+ end
212
+
213
+ it "creates a partition_all transducer" do
214
+ expect([[1,2],[3,4],[5,6]]) do
215
+ T.transduce(T.partition_all(2), :<<, [], 1..6)
216
+ end
217
+
218
+ expect([[1,2],[3,4],[5,6],[7]]) do
219
+ T.transduce(T.partition_all(2), :<<, [], 1..7)
220
+ end
221
+ end
222
+
223
+ it "creates a random_sample transducer" do
224
+ # These are admittedly just sanity checks.
225
+ expect(true) do
226
+ result = T.transduce(T.random_sample(0.5), :<<, [], 1..1000)
227
+ min, max = 400, 600
228
+ raise "Expected between #{min} and #{max}, got #{result.count}" unless
229
+ result.count.between?(min,max)
230
+ true
231
+ end
232
+
233
+ expect(true) do
234
+ result = T.transduce(T.random_sample(0.75), :<<, [], 1..1000)
235
+ min, max = 650, 850
236
+ raise "Expected between #{min} and #{max}, got #{result.count}" unless
237
+ result.count.between?(min,max)
238
+ true
239
+ end
240
+ end
241
+
242
+ it "transduces a String" do
243
+ expect("THIS") do
244
+ T.transduce(T.map {|c| c.upcase},
245
+ Transducers::Reducer.new("") {|r,i| r << i},
246
+ "this")
247
+ end
248
+ end
249
+
250
+ it "transduces a range" do
251
+ expect([2,3,4]) do
252
+ T.transduce(T.map(:succ), :<<, [], 1..3)
253
+ end
254
+ end
255
+
256
+ it "raises when no initial value method is defined on the reducer" do
257
+ orig_expect do
258
+ r = Class.new { def step(_,_) end }.new
259
+ T.transduce(T.map(:succ), r, [1,2,3])
260
+ end.to raise_error(NoMethodError)
261
+ end
262
+
263
+ it "raises when it receives a symbol but no initial value" do
264
+ orig_expect do
265
+ T.transduce(T.map(:succ), :<<, [1,2,3])
266
+ end.to raise_error(ArgumentError, "No init provided")
267
+ end
268
+
269
+ describe "composition" do
270
+ example do
271
+ expect([3,7]) do
272
+ td = T.compose(T.map {|a| [a.reduce(&:+)]}, T.cat)
273
+ T.transduce(td, :<<, [], [[1,2],[3,4]])
274
+ end
275
+ end
276
+
277
+ example do
278
+ expect(12) do
279
+ td = T.compose(T.take(5),
280
+ T.map {|n| n + 1},
281
+ T.filter(:even?))
282
+ T.transduce(td, :+, 0, 1..20)
283
+ end
284
+ end
285
+ end
286
+ end
@@ -0,0 +1,34 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "transducers"
7
+ spec.version = "0.4.94"
8
+ spec.authors = ["David Chelimsky"]
9
+ spec.email = ["dchelimsky@cognitect.com"]
10
+ spec.summary = %q{Transducers for Ruby}
11
+ spec.description = %q{Transducers, composable algorithmic transformations}
12
+ spec.homepage = "https://github.com/cognitect-labs/transducers-ruby"
13
+ spec.license = "Apache License 2.0"
14
+
15
+ spec.files = `git ls-files -z`.split("\x0")
16
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
+ spec.require_paths = ["lib"]
19
+
20
+ spec.add_development_dependency "bundler", "~> 1.7"
21
+ spec.add_development_dependency "rake", "~> 10.0"
22
+ spec.add_development_dependency "rspec", "~> 3.0"
23
+ spec.add_development_dependency "yard", "~> 0.8.7.4"
24
+ spec.add_development_dependency "redcarpet", "~> 3.1.1"
25
+ spec.add_development_dependency "yard-redcarpet-ext", "~> 0.0.3"
26
+
27
+ private_key = File.expand_path(File.join(ENV['HOME'], '.gem/transit-ruby/private-key.pem'))
28
+ public_key = File.expand_path(File.join(ENV['HOME'], '.gem/transit-ruby/public-key.pem'))
29
+
30
+ if File.exist?(private_key) && ENV['SIGN'] == 'true'
31
+ spec.signing_key = private_key
32
+ spec.cert_chain = [public_key]
33
+ end
34
+ end
metadata ADDED
@@ -0,0 +1,151 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: transducers
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.4.94
5
+ platform: ruby
6
+ authors:
7
+ - David Chelimsky
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-10-10 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.7'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.7'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: yard
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 0.8.7.4
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 0.8.7.4
69
+ - !ruby/object:Gem::Dependency
70
+ name: redcarpet
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 3.1.1
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 3.1.1
83
+ - !ruby/object:Gem::Dependency
84
+ name: yard-redcarpet-ext
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: 0.0.3
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: 0.0.3
97
+ description: Transducers, composable algorithmic transformations
98
+ email:
99
+ - dchelimsky@cognitect.com
100
+ executables:
101
+ - rspec-across-supported-versions
102
+ extensions: []
103
+ extra_rdoc_files: []
104
+ files:
105
+ - ".gitignore"
106
+ - ".rspec"
107
+ - ".yardopts"
108
+ - Gemfile
109
+ - LICENSE
110
+ - README.md
111
+ - Rakefile
112
+ - benchmarks/arguments_to_filter.rb
113
+ - benchmarks/arguments_to_map.rb
114
+ - benchmarks/transducers_v_ruby_iterators.rb
115
+ - bin/rspec-across-supported-versions
116
+ - build/revision
117
+ - dev/irb_tools.rb
118
+ - lib/transducers.rb
119
+ - spec/spec_helper.rb
120
+ - spec/transducers/reducer_spec.rb
121
+ - spec/transducers_spec.rb
122
+ - transducers.gemspec
123
+ homepage: https://github.com/cognitect-labs/transducers-ruby
124
+ licenses:
125
+ - Apache License 2.0
126
+ metadata: {}
127
+ post_install_message:
128
+ rdoc_options: []
129
+ require_paths:
130
+ - lib
131
+ required_ruby_version: !ruby/object:Gem::Requirement
132
+ requirements:
133
+ - - ">="
134
+ - !ruby/object:Gem::Version
135
+ version: '0'
136
+ required_rubygems_version: !ruby/object:Gem::Requirement
137
+ requirements:
138
+ - - ">="
139
+ - !ruby/object:Gem::Version
140
+ version: '0'
141
+ requirements: []
142
+ rubyforge_project:
143
+ rubygems_version: 2.3.0
144
+ signing_key:
145
+ specification_version: 4
146
+ summary: Transducers for Ruby
147
+ test_files:
148
+ - spec/spec_helper.rb
149
+ - spec/transducers/reducer_spec.rb
150
+ - spec/transducers_spec.rb
151
+ has_rdoc: