casegen 2.0.0 → 3.0.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 +4 -4
- data/.rspec +1 -0
- data/.rubocop.yml +109 -0
- data/.ruby-version +1 -1
- data/Gemfile +3 -1
- data/Gemfile.lock +51 -6
- data/README.md +10 -119
- data/Rakefile +9 -7
- data/bin/casegen +2 -1
- data/casegen.gemspec +13 -9
- data/doc/bounding_box.rb +37 -0
- data/doc/cart.rb +43 -0
- data/doc/expect_only.rb +28 -0
- data/doc/pricing.rb +50 -0
- data/doc/ruby_array.rb +41 -0
- data/lib/case_gen/combination.rb +38 -0
- data/lib/case_gen/combo_matcher.rb +15 -0
- data/lib/case_gen/exclude_rule.rb +50 -0
- data/lib/case_gen/expect_rule.rb +24 -0
- data/lib/case_gen/generator.rb +40 -0
- data/lib/case_gen/output/exclude.rb +6 -0
- data/lib/case_gen/output/exclude_as_table.rb +13 -0
- data/lib/case_gen/output/exclude_as_text.rb +12 -0
- data/lib/case_gen/output/exclude_inline.rb +13 -0
- data/lib/case_gen/output/exclude_inline_footnotes.rb +20 -0
- data/lib/case_gen/output.rb +66 -0
- data/lib/case_gen/rule_description.rb +11 -0
- data/lib/case_gen/set.rb +16 -0
- data/lib/casegen.rb +15 -183
- data/spec/cart_sample_spec.rb +46 -0
- data/spec/case_gen/combination_spec.rb +11 -0
- data/spec/case_gen/exclude_rule_spec.rb +17 -0
- data/spec/exclude_as_table_spec.rb +39 -0
- data/spec/exclude_as_text_spec.rb +58 -0
- data/spec/exclude_inline_footnotes_spec.rb +58 -0
- data/spec/exclude_inline_spec.rb +50 -0
- data/spec/expect_only_spec.rb +30 -0
- data/spec/spec_helper.rb +113 -0
- metadata +101 -35
- data/.idea/encodings.xml +0 -5
- data/.idea/misc.xml +0 -5
- data/.idea/modules.xml +0 -9
- data/.idea/vcs.xml +0 -7
- data/doc/calc.sample.txt +0 -13
- data/doc/cart.sample.rb +0 -3
- data/doc/cart.sample.txt +0 -33
- data/doc/ruby_array.sample.rb +0 -26
- data/lib/agents/sets/enum/by.rb +0 -244
- data/lib/agents/sets/enum/cluster.rb +0 -164
- data/lib/agents/sets/enum/inject.rb +0 -50
- data/lib/agents/sets/enum/nest.rb +0 -117
- data/lib/agents/sets/enum/op.rb +0 -283
- data/lib/agents/sets/enum/pipe.rb +0 -160
- data/lib/agents/sets/enum/tree.rb +0 -442
- data/lib/agents/sets.rb +0 -313
- data/test/agents/console_output_test.rb +0 -27
- data/test/agents/sets.test.rb +0 -227
- data/test/agents_test.rb +0 -41
- data/test/casegen.tests.rb +0 -0
- data/test/parser_test.rb +0 -163
- data/test/test_helper.rb +0 -2
@@ -1,117 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
module Enumerable
|
4
|
-
|
5
|
-
def nest(&compare)
|
6
|
-
ary = to_a
|
7
|
-
s = ary.size
|
8
|
-
i = 0
|
9
|
-
|
10
|
-
# wrap into Array::Iterator?
|
11
|
-
items_left = proc { i < s }
|
12
|
-
get_cur = proc { ary[i] }
|
13
|
-
go_next = proc { i += 1 }
|
14
|
-
|
15
|
-
result = nil
|
16
|
-
while items_left[]
|
17
|
-
level_ary = Enumerable.nest items_left, get_cur, go_next, compare
|
18
|
-
result = result ? level_ary.unshift(result) : level_ary
|
19
|
-
end
|
20
|
-
result || []
|
21
|
-
end
|
22
|
-
|
23
|
-
# Handles a single level, recursing when the depth increases and
|
24
|
-
# backing out when the depth decreases.
|
25
|
-
def Enumerable.nest items_left, get_cur, go_next, compare
|
26
|
-
# should handle compare.arity == 2 like a <=> proc
|
27
|
-
result = []; item = depth = nil
|
28
|
-
while items_left[]
|
29
|
-
item = get_cur[]
|
30
|
-
depth = compare[item]
|
31
|
-
base_depth ||= depth
|
32
|
-
|
33
|
-
if depth < base_depth
|
34
|
-
break
|
35
|
-
elsif depth > base_depth
|
36
|
-
result << nest(items_left, get_cur, go_next, compare)
|
37
|
-
else
|
38
|
-
result << item; go_next[]
|
39
|
-
end
|
40
|
-
end
|
41
|
-
return result
|
42
|
-
end
|
43
|
-
|
44
|
-
def group(&test)
|
45
|
-
nest { |x| test[x] ? 1 : 0 }
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
=begin
|
50
|
-
|
51
|
-
=module Enumerable
|
52
|
-
==instance methods
|
53
|
-
---Enumerable#nest &compare
|
54
|
-
|
55
|
-
(({nest})) is an inverse for (({Array#flatten})). (Well, actually only a right
|
56
|
-
inverse since (({flatten})) is not injective.) You give it a proc that
|
57
|
-
calculates the depth of each item, and it returns a nesting of arrays in which
|
58
|
-
each item has the desired depth. It can be used to parse strings with
|
59
|
-
Python-like indentation syntax, but it isn't limited to strings.
|
60
|
-
|
61
|
-
The main improvement in this version is that the compare block can return
|
62
|
-
a lower value for an element after the first, with the expected effect. See the first example at the end of the source file.
|
63
|
-
|
64
|
-
===version
|
65
|
-
|
66
|
-
Enumerable tools 1.6
|
67
|
-
|
68
|
-
The current version of this software can be found at
|
69
|
-
((<"http://redshift.sourceforge.net/enum
|
70
|
-
"|URL:http://redshift.sourceforge.net/enum>)).
|
71
|
-
|
72
|
-
===license
|
73
|
-
This software is distributed under the Ruby license.
|
74
|
-
See ((<"http://www.ruby-lang.org"|URL:http://www.ruby-lang.org>)).
|
75
|
-
|
76
|
-
===author
|
77
|
-
Joel VanderWerf,
|
78
|
-
((<vjoel@users.sourceforge.net|URL:mailto:vjoel@users.sourceforge.net>))
|
79
|
-
|
80
|
-
=end
|
81
|
-
|
82
|
-
if __FILE__ == $0
|
83
|
-
|
84
|
-
str = <<END
|
85
|
-
a
|
86
|
-
aa
|
87
|
-
ab
|
88
|
-
aba
|
89
|
-
abb
|
90
|
-
abba
|
91
|
-
abbaa
|
92
|
-
abbb
|
93
|
-
ac
|
94
|
-
ad
|
95
|
-
ada
|
96
|
-
adaa
|
97
|
-
adb
|
98
|
-
b
|
99
|
-
ba
|
100
|
-
bb
|
101
|
-
c
|
102
|
-
ca
|
103
|
-
X
|
104
|
-
Y
|
105
|
-
Z
|
106
|
-
END
|
107
|
-
|
108
|
-
lines = str.split "\n"
|
109
|
-
nested = lines.nest { |line| /\S/ =~ line }
|
110
|
-
p nested
|
111
|
-
flat = nested.flatten
|
112
|
-
p flat
|
113
|
-
p flat == lines
|
114
|
-
|
115
|
-
p [1, 2, "three", "four", 5, "six"].group { |x| x.is_a? String }
|
116
|
-
|
117
|
-
end
|
data/lib/agents/sets/enum/op.rb
DELETED
@@ -1,283 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
require 'enum/inject'
|
4
|
-
|
5
|
-
module EnumerableOperator
|
6
|
-
|
7
|
-
class Product
|
8
|
-
include Enumerable
|
9
|
-
|
10
|
-
attr_reader :factors, :dim
|
11
|
-
|
12
|
-
def initialize(*factors)
|
13
|
-
@factors = factors
|
14
|
-
@dim = @factors.length
|
15
|
-
end
|
16
|
-
|
17
|
-
def each tuple = [nil]*@dim, i = 0, &block
|
18
|
-
if i == @dim - 1 then
|
19
|
-
@factors[i].each { |x| tuple[i] = x; yield tuple.dup }
|
20
|
-
elsif i > 0
|
21
|
-
@factors[i].each { |x| tuple[i] = x; each tuple, i + 1, &block }
|
22
|
-
else
|
23
|
-
@factors[i].each { |x| tuple[i] = x; each tuple, i + 1, &block }
|
24
|
-
self
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
def size
|
29
|
-
@factors.product { |enum| enum.size }
|
30
|
-
end
|
31
|
-
|
32
|
-
end
|
33
|
-
|
34
|
-
class Sum
|
35
|
-
include Enumerable
|
36
|
-
|
37
|
-
attr_reader :summands
|
38
|
-
|
39
|
-
def initialize(*summands)
|
40
|
-
@summands = summands
|
41
|
-
end
|
42
|
-
|
43
|
-
def each(&block)
|
44
|
-
@summands.each { |enum| enum.each(&block) }
|
45
|
-
self
|
46
|
-
end
|
47
|
-
|
48
|
-
def size
|
49
|
-
@summands.sum { |enum| enum.size }
|
50
|
-
end
|
51
|
-
|
52
|
-
end
|
53
|
-
|
54
|
-
class Diagonal
|
55
|
-
include Enumerable
|
56
|
-
|
57
|
-
attr_reader :factors, :dim
|
58
|
-
|
59
|
-
def initialize(*factors)
|
60
|
-
@factors = factors
|
61
|
-
@dim = @factors.length
|
62
|
-
end
|
63
|
-
|
64
|
-
def each
|
65
|
-
factors = @factors.map { |factor|
|
66
|
-
if factor.kind_of? Array then factor else factor.entries end
|
67
|
-
}
|
68
|
-
minlength = factors.min { |f, g| f.length <=> g.length }.length
|
69
|
-
for i in 0..(minlength-1)
|
70
|
-
yield factors.map { |factor| factor[i] }
|
71
|
-
end
|
72
|
-
self
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
|
77
|
-
def product(*factors, &block)
|
78
|
-
if block
|
79
|
-
Product.new(*factors).each(&block)
|
80
|
-
else
|
81
|
-
Product.new(*factors)
|
82
|
-
end
|
83
|
-
end
|
84
|
-
alias :tuples :product
|
85
|
-
|
86
|
-
def sum(*summands, &block)
|
87
|
-
if block
|
88
|
-
Sum.new(*summands).each(&block)
|
89
|
-
else
|
90
|
-
Sum.new(*summands)
|
91
|
-
end
|
92
|
-
end
|
93
|
-
alias :concatenation :sum
|
94
|
-
alias :cat :sum
|
95
|
-
|
96
|
-
def diagonal(*factors, &block)
|
97
|
-
if block
|
98
|
-
Diagonal.new(*factors).each(&block)
|
99
|
-
else
|
100
|
-
Diagonal.new(*factors)
|
101
|
-
end
|
102
|
-
end
|
103
|
-
|
104
|
-
module_function :product, :sum, :diagonal
|
105
|
-
end
|
106
|
-
|
107
|
-
=begin
|
108
|
-
|
109
|
-
==module EnumerableOperator
|
110
|
-
===instance methods and module methods
|
111
|
-
---EnumerableOperator#product *factors, &block
|
112
|
-
---EnumerableOperator#sum *summands, &block
|
113
|
-
|
114
|
-
The (({product})) operator iterates over the Cartesian product of the factors,
|
115
|
-
each of which must be (({Enumerable})).
|
116
|
-
|
117
|
-
The (({sum})) operator iterates over the concatenation of the summands, each of
|
118
|
-
which must be (({Enumerable})).
|
119
|
-
|
120
|
-
Both operators have aliases: (({tuples})) for (({product}));
|
121
|
-
(({concatenation})) and (({cat})) for (({sum})).
|
122
|
-
|
123
|
-
Called with a block, the operators yield one element of the sequence at a time
|
124
|
-
to the block.
|
125
|
-
|
126
|
-
With or without a block, the operators return an (({Enumerable})) which
|
127
|
-
delegates to the original (({Enumerables})), but does not explicitly construct
|
128
|
-
the entire collection. Calling another (({Enumerable})) method, such as
|
129
|
-
(({select})) or (({collect})), on this return value is an efficient way of
|
130
|
-
chaining these operators with other methods. Simply call (({entries})) to get
|
131
|
-
the whole collection. Also, because the operators return an (({Enumerable})),
|
132
|
-
they can be used with the (({for})) syntax; see the examples.
|
133
|
-
|
134
|
-
---EnumerableOperator#diagonal *factors, &block
|
135
|
-
|
136
|
-
The (({diagonal})) operator iterates over the diagonal of the Cartesian product
|
137
|
-
of the factors, each of which must be (({Enumerable})). In other words, the
|
138
|
-
n-th entry of the diagonal is an array of the n-th entries of each factor. The
|
139
|
-
resulting sequence terminates when any one factor terminates. Hence the
|
140
|
-
sequence has the same length as the shortest factor.
|
141
|
-
|
142
|
-
Called with a block, (({diagonal})) yields one element of the sequence at a
|
143
|
-
time to the block.
|
144
|
-
|
145
|
-
With or without a block, (({diagonal})) returns an (({Enumerable})) object
|
146
|
-
which is ((*independent*)) of the original (({Enumerables})). As with
|
147
|
-
(({product})) and (({sum})), this allows chaining with other iterators and
|
148
|
-
using the (({for})) syntax. Unlike (({product})) and (({sum})), however, the
|
149
|
-
entire collection is generated and stored in the object returned by
|
150
|
-
(({diagonal})).
|
151
|
-
|
152
|
-
Internally, (({diagonal})) does not enumerate the sequences in parallel, but in
|
153
|
-
the order in which they are given. If the sequences have side-effects of
|
154
|
-
enumeration, this may result in different behavior than if the sequences were
|
155
|
-
truly enumerated in parallel (e.g., see matz's approach using threads in the
|
156
|
-
Ruby FAQ: ((<"http://www.rubycentral.com/faq/rubyfaq-5.html#ss5.5
|
157
|
-
"|URL:http://www.rubycentral.com/faq/rubyfaq-5.html#ss5.5>))).
|
158
|
-
|
159
|
-
===usage
|
160
|
-
|
161
|
-
include EnumerableOperator
|
162
|
-
diagonal enum0, enum1, ...
|
163
|
-
or
|
164
|
-
EnumerableOperator.diagonal enum0, enum1, ...
|
165
|
-
and similarly for product and sum.
|
166
|
-
|
167
|
-
===examples
|
168
|
-
|
169
|
-
require 'enum/op'
|
170
|
-
include EnumerableOperator
|
171
|
-
|
172
|
-
# using the 'for ... in ... end' construct:
|
173
|
-
for i, j in product 1..4, "bar".."baz"
|
174
|
-
printf "%6s", i.to_s + j; puts if j == "baz"
|
175
|
-
end
|
176
|
-
puts
|
177
|
-
|
178
|
-
# prints:
|
179
|
-
# 1bar 1bas 1bat 1bau 1bav 1baw 1bax 1bay 1baz
|
180
|
-
# 2bar 2bas 2bat 2bau 2bav 2baw 2bax 2bay 2baz
|
181
|
-
# 3bar 3bas 3bat 3bau 3bav 3baw 3bax 3bay 3baz
|
182
|
-
|
183
|
-
# directly passing a block:
|
184
|
-
sum 1..5, 'a'..'c', 90..92 do |i|
|
185
|
-
printf "%4s", i.to_s
|
186
|
-
end
|
187
|
-
puts "\n\n"
|
188
|
-
|
189
|
-
# prints:
|
190
|
-
# 1 2 3 4 5 a b c 90 91 92
|
191
|
-
|
192
|
-
for i, j, k in diagonal 1..4, 'a'..'d', ?a..?d
|
193
|
-
printf "%4d. %s is 0x%x\n", i, j, k
|
194
|
-
end
|
195
|
-
puts
|
196
|
-
|
197
|
-
# prints:
|
198
|
-
# 1. a is 0x61
|
199
|
-
# 2. b is 0x62
|
200
|
-
# 3. c is 0x63
|
201
|
-
# 4. d is 0x64
|
202
|
-
|
203
|
-
# chaining with other iterators:
|
204
|
-
names = %w{ Ludwig Rudolf Bertrand Willard }
|
205
|
-
more_names = %w{ Jean-Paul Albert Martin Soren }
|
206
|
-
puts sum(names, more_names).sort.join ', '
|
207
|
-
puts
|
208
|
-
|
209
|
-
# prints:
|
210
|
-
# Albert, Bertrand, Jean-Paul, Ludwig, Martin, Rudolf, Soren, Willard
|
211
|
-
|
212
|
-
# note that chaining avoids constructing the intermediate collection:
|
213
|
-
big_product = product 1..10, 1..10, 1..10
|
214
|
-
big_product.select { |x, y, z|
|
215
|
-
x <= y and x**2 + y**2 == z**2
|
216
|
-
}.each { |x, y, z|
|
217
|
-
printf "#{x}**2 + #{y}**2 == #{z}**2\n"
|
218
|
-
}
|
219
|
-
|
220
|
-
# prints:
|
221
|
-
# 3**2 + 4**2 == 5**2
|
222
|
-
# 6**2 + 8**2 == 10**2
|
223
|
-
|
224
|
-
==version
|
225
|
-
|
226
|
-
Enumerable tools 1.6
|
227
|
-
|
228
|
-
The current version of this software can be found at
|
229
|
-
((<"http://redshift.sourceforge.net/enum
|
230
|
-
"|URL:http://redshift.sourceforge.net/enum>)).
|
231
|
-
|
232
|
-
==license
|
233
|
-
This software is distributed under the Ruby license.
|
234
|
-
See ((<"http://www.ruby-lang.org"|URL:http://www.ruby-lang.org>)).
|
235
|
-
|
236
|
-
==author
|
237
|
-
Joel VanderWerf,
|
238
|
-
((<vjoel@users.sourceforge.net|URL:mailto:vjoel@users.sourceforge.net>))
|
239
|
-
|
240
|
-
=end
|
241
|
-
|
242
|
-
|
243
|
-
if __FILE__ == $0
|
244
|
-
|
245
|
-
include EnumerableOperator
|
246
|
-
|
247
|
-
# using the 'for ... in ... end' construct:
|
248
|
-
for i, j in product 1..4, "bar".."baz"
|
249
|
-
printf "%6s", i.to_s + j; puts if j == "baz"
|
250
|
-
end
|
251
|
-
puts
|
252
|
-
|
253
|
-
# directly passing a block:
|
254
|
-
sum 1..5, 'a'..'c', 90..92 do |i|
|
255
|
-
printf "%4s", i.to_s
|
256
|
-
end
|
257
|
-
puts "\n\n"
|
258
|
-
|
259
|
-
for i, j, k in diagonal 1..4, 'a'..'d', ?a..?d
|
260
|
-
printf "%4d. %s is 0x%x\n", i, j, k
|
261
|
-
end
|
262
|
-
puts
|
263
|
-
|
264
|
-
# chaining with other iterators:
|
265
|
-
names = %w{ Ludwig Rudolf Bertrand Willard }
|
266
|
-
more_names = %w{ Jean-Paul Albert Martin Soren }
|
267
|
-
puts sum(names, more_names).sort.join(', ')
|
268
|
-
puts
|
269
|
-
|
270
|
-
# note that chaining avoids constructing the intermediate collection:
|
271
|
-
big_product = product 1..10, 1..10, 1..10
|
272
|
-
big_product.select { |x, y, z|
|
273
|
-
x <= y and x**2 + y**2 == z**2
|
274
|
-
}.each { |x, y, z|
|
275
|
-
printf "#{x}**2 + #{y}**2 == #{z}**2\n"
|
276
|
-
}
|
277
|
-
puts
|
278
|
-
|
279
|
-
# size
|
280
|
-
puts "sum(1..10,11..20).size = #{sum(1..10,11..20).size}"
|
281
|
-
puts "product(1..10,11..20).size = #{product(1..10,11..20).size}"
|
282
|
-
puts "product([1,2,3],[]).size = #{product([1,2,3],[]).size}"
|
283
|
-
end
|
@@ -1,160 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
module Enumerable
|
4
|
-
|
5
|
-
class Pipe
|
6
|
-
include Enumerable
|
7
|
-
|
8
|
-
attr_reader :enum, :filter_name, :filter_map, :args
|
9
|
-
|
10
|
-
def initialize enum, filter_spec = nil, *args, &filter_proc
|
11
|
-
@enum = enum
|
12
|
-
@args = args
|
13
|
-
|
14
|
-
case filter_spec
|
15
|
-
when Symbol
|
16
|
-
@filter_name = filter_spec
|
17
|
-
when String
|
18
|
-
@filter_name = filter_spec.intern
|
19
|
-
when nil
|
20
|
-
@filter_map = filter_proc
|
21
|
-
else
|
22
|
-
unless filter_spec.respond_to? :[]
|
23
|
-
raise ArgumentError,
|
24
|
-
"filter_spec must be a method name or respond to []."
|
25
|
-
end
|
26
|
-
@filter_map = filter_spec
|
27
|
-
end
|
28
|
-
|
29
|
-
unless @filter_name or @filter_map
|
30
|
-
raise ArgumentError,
|
31
|
-
"no filter specified."
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
def each
|
36
|
-
if @filter_name
|
37
|
-
filter_name = @filter_name
|
38
|
-
message = filter_name, *@args
|
39
|
-
@enum.each { |entry|
|
40
|
-
yield entry.send *message
|
41
|
-
}
|
42
|
-
elsif @filter_map
|
43
|
-
filter_map = @filter_map
|
44
|
-
args = *@args
|
45
|
-
@enum.each { |entry|
|
46
|
-
yield filter_map[entry, *args]
|
47
|
-
}
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
self
|
52
|
-
end
|
53
|
-
|
54
|
-
def pipe filter_spec = nil, *args, &filter_proc
|
55
|
-
Pipe.new self, filter_spec, *args, &filter_proc
|
56
|
-
end
|
57
|
-
|
58
|
-
end
|
59
|
-
|
60
|
-
|
61
|
-
=begin
|
62
|
-
|
63
|
-
==class Enumerable
|
64
|
-
===instance method
|
65
|
-
---Enumerable#pipe filter_spec = nil, *args, &filter_proc
|
66
|
-
|
67
|
-
Can be used to "pipe" an (({Enumerable})) sequence through a filter.
|
68
|
-
|
69
|
-
(({Enumerable#pipe})) returns an (({Enumerable})) object whose (({each}))
|
70
|
-
method iterates over (({self})) and applies a filter to each enumerated
|
71
|
-
object, as specified by the arguments. Only the current element of the
|
72
|
-
sequence is kept in memory.
|
73
|
-
|
74
|
-
If (({filter_spec})) is a string or symbol, (({filter_proc})) is ignored
|
75
|
-
and (({filter_spec})) is treated as a method name. This method name is
|
76
|
-
sent, along with arguments (({args})), to each element of the sequence
|
77
|
-
being enumerated.
|
78
|
-
|
79
|
-
If (({filter_spec})) is anything else, except (({nil})), (({filter_proc}))
|
80
|
-
is ignored and (({filter_spec})) is required to be an object that responds
|
81
|
-
to (({[]})), such as a proc or a hash. The (({[]})) method of
|
82
|
-
(({filter_spec})) is called with each element of the sequence in turn as
|
83
|
-
an argument, along with (({args})).
|
84
|
-
|
85
|
-
If (({next_spec})) is not given, or is (({nil})), a block is required. In
|
86
|
-
this case, iteration proceeds as in the preceding paragraph.
|
87
|
-
|
88
|
-
Using (({#pipe})) has potential performance advantages. The iteration
|
89
|
-
|
90
|
-
e.collect { |x| x.m }.each { |y| ... }
|
91
|
-
|
92
|
-
can be rewritten as
|
93
|
-
|
94
|
-
e.pipe(:m).each { |y| ... }
|
95
|
-
|
96
|
-
which doesn't generate an intermediate array, and uses a send instead of a
|
97
|
-
proc call. Of course, it could also be written as
|
98
|
-
|
99
|
-
e.each { |x| y = x.m ... }
|
100
|
-
|
101
|
-
but that may be undesirable for readability or because the block is to be
|
102
|
-
taken from a proc contained in a variable:
|
103
|
-
|
104
|
-
pr = proc { ... }
|
105
|
-
e.pipe(:m).each &pr
|
106
|
-
|
107
|
-
Also, chains of (({collect})) and (({select})), such as
|
108
|
-
|
109
|
-
(1..100).collect { |x| x**2 }.select { |y| y > 1000 && y < 2000 }
|
110
|
-
|
111
|
-
can't be easily rewritten as a single (({select})).
|
112
|
-
|
113
|
-
===examples
|
114
|
-
|
115
|
-
require 'enum/pipe'
|
116
|
-
|
117
|
-
[0,1,2,3,4].pipe { |x| x + 1 }.each { |x|
|
118
|
-
print x, " "
|
119
|
-
}
|
120
|
-
|
121
|
-
# prints: 1 2 3 4 5
|
122
|
-
|
123
|
-
stooges = ['lARRY', 'cURLY', 'mOE']
|
124
|
-
p stooges.pipe(:swapcase).reject { |x| x =~ /url/ }
|
125
|
-
p stooges.pipe(:tr, 'RlcOEL', 'gBboog').pipe(:capitalize).entries
|
126
|
-
|
127
|
-
# prints: ["Larry", "Moe"]
|
128
|
-
# ["Baggy", "Buggy", "Moo"]
|
129
|
-
|
130
|
-
==version
|
131
|
-
|
132
|
-
Enumerable tools 1.6
|
133
|
-
|
134
|
-
The current version of this software can be found at
|
135
|
-
((<"http://redshift.sourceforge.net/enum
|
136
|
-
"|URL:http://redshift.sourceforge.net/enum>)).
|
137
|
-
|
138
|
-
==license
|
139
|
-
This software is distributed under the Ruby license.
|
140
|
-
See ((<"http://www.ruby-lang.org"|URL:http://www.ruby-lang.org>)).
|
141
|
-
|
142
|
-
==author
|
143
|
-
Joel VanderWerf,
|
144
|
-
((<vjoel@users.sourceforge.net|URL:mailto:vjoel@users.sourceforge.net>))
|
145
|
-
|
146
|
-
=end
|
147
|
-
|
148
|
-
|
149
|
-
if __FILE__ == $0
|
150
|
-
|
151
|
-
[0,1,2,3,4].pipe { |x| x + 1 }.each { |x|
|
152
|
-
print x, " "
|
153
|
-
}
|
154
|
-
puts
|
155
|
-
|
156
|
-
stooges = ['lARRY', 'cURLY', 'mOE']
|
157
|
-
p stooges.pipe(:swapcase).reject { |x| x =~ /url/ }
|
158
|
-
p stooges.pipe(:tr, 'RlcOEL', 'gBboog').pipe(:capitalize).entries
|
159
|
-
|
160
|
-
end
|