rdx 0.9.0.pre
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 +7 -0
- data/.rdx +20 -0
- data/README +19 -0
- data/bin/rdx +7 -0
- data/examples/minimal/.rdx +8 -0
- data/examples/minimal/README +10 -0
- data/examples/minimal/lib/other_conventions.rb +64 -0
- data/examples/minimal/lib/the_basics.rb +94 -0
- data/examples/minimal/lib/using_directives.rb +66 -0
- data/examples/minimal/rakefile +27 -0
- data/examples/ruby-2.0.0-p0/README +7 -0
- data/examples/ruby-2.0.0-p0/install/core/.rdx +6 -0
- data/examples/ruby-2.0.0-p0/install/core/README +19 -0
- data/examples/ruby-2.0.0-p0/install/core/Rakefile +61 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/array.c.diff +166 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/bignum.c.diff +11 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/class.c.diff +36 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/compar.c.diff +11 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/complex.c.diff +301 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/cont.c.diff +65 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/dir.c.diff +147 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/doc/re.rdoc.diff +328 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/doc/security.rdoc.diff +8 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/doc/standard_library.rdoc.diff +0 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/doc/syntax.rdoc.diff +0 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/doc/syntax/assignment.rdoc.diff +160 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/doc/syntax/calling_methods.rdoc.diff +130 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/doc/syntax/control_expressions.rdoc.diff +254 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/doc/syntax/exceptions.rdoc.diff +0 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/doc/syntax/literals.rdoc.diff +54 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/doc/syntax/methods.rdoc.diff +157 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/doc/syntax/miscellaneous.rdoc.diff +91 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/doc/syntax/modules_and_classes.rdoc.diff +161 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/doc/syntax/precedence.rdoc.diff +8 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/doc/syntax/refinements.rdoc.diff +146 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/encoding.c.diff +276 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/enum.c.diff +281 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/enumerator.c.diff +479 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/error.c.diff +143 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/eval.c.diff +47 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/eval_jump.c.diff +23 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/file.c.diff +752 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/gc.c.diff +195 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/hash.c.diff +84 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/iseq.c.diff +354 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/load.c.diff +53 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/marshal.c.diff +98 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/math.c.diff +110 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/numeric.c.diff +103 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/object.c.diff +295 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/pack.c.diff +18 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/parse.y.diff +23 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/proc.c.diff +155 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/random.c.diff +126 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/range.c.diff +49 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/rational.c.diff +312 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/re.c.diff +207 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/ruby.c.diff +21 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/signal.c.diff +67 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/sprintf.c.diff +29 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/string.c.diff +73 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/struct.c.diff +20 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/time.c.diff +691 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/transcode.c.diff +435 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/variable.c.diff +62 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/vm_backtrace.c.diff +164 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/vm_eval.c.diff +99 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/vm_method.c.diff +17 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/vm_trace.c.diff +393 -0
- data/examples/ruby-2.0.0-p0/install/stdlib/.rdx +6 -0
- data/examples/ruby-2.0.0-p0/install/stdlib/README +19 -0
- data/examples/ruby-2.0.0-p0/install/stdlib/Rakefile +53 -0
- data/examples/ruby-2.0.0-p0/install/stdlib/diffs/lib/abbrev.rb.diff +77 -0
- data/examples/ruby-2.0.0-p0/install/stdlib/diffs/lib/base64.rb.diff +42 -0
- data/examples/ruby-2.0.0-p0/install/stdlib/diffs/lib/benchmark.rb.diff +144 -0
- data/examples/ruby-2.0.0-p0/install/stdlib/diffs/lib/cmath.rb.diff +52 -0
- data/examples/ruby-2.0.0-p0/install/stdlib/diffs/lib/forwardable.rb.diff +150 -0
- data/examples/ruby-2.0.0-p0/install/stdlib/diffs/lib/mathn.rb.diff +58 -0
- data/examples/ruby-2.0.0-p0/install/stdlib/diffs/lib/matrix.rb.diff +657 -0
- data/examples/ruby-2.0.0-p0/install/stdlib/diffs/lib/observer.rb.diff +31 -0
- data/examples/ruby-2.0.0-p0/install/stdlib/diffs/lib/optparse.rb.diff +147 -0
- data/examples/ruby-2.0.0-p0/install/stdlib/diffs/lib/ostruct.rb.diff +78 -0
- data/examples/ruby-2.0.0-p0/install/stdlib/diffs/lib/prime.rb.diff +52 -0
- data/examples/ruby-2.0.0-p0/install/stdlib/diffs/lib/pstore.rb.diff +110 -0
- data/examples/ruby-2.0.0-p0/install/stdlib/diffs/lib/scanf.rb.diff +100 -0
- data/examples/ruby-2.0.0-p0/install/stdlib/diffs/lib/securerandom.rb.diff +144 -0
- data/examples/ruby-2.0.0-p0/install/stdlib/diffs/lib/set.rb.diff +637 -0
- data/examples/ruby-2.0.0-p0/install/stdlib/diffs/lib/shellwords.rb.diff +66 -0
- data/examples/ruby-2.0.0-p0/install/stdlib/diffs/lib/singleton.rb.diff +37 -0
- data/examples/ruby-2.0.0-p0/install/stdlib/diffs/lib/tempfile.rb.diff +104 -0
- data/examples/ruby-2.0.0-p0/install/stdlib/diffs/lib/thread.rb.diff +38 -0
- data/examples/ruby-2.0.0-p0/install/stdlib/diffs/lib/time.rb.diff +140 -0
- data/examples/ruby-2.0.0-p0/install/stdlib/diffs/lib/tmpdir.rb.diff +52 -0
- data/examples/ruby-2.0.0-p0/install/stdlib/diffs/lib/uri.rb.diff +39 -0
- data/examples/ruby-2.0.0-p0/install/stdlib/diffs/lib/uri/common.rb.diff +237 -0
- data/examples/ruby-2.0.0-p0/install/stdlib/diffs/lib/weakref.rb.diff +36 -0
- data/examples/ruby-2.0.0-p0/install/stdlib/diffs/lib/yaml/store.rb.diff +27 -0
- data/examples/ruby-2.0.0-p0/rakefile +165 -0
- data/lib/rdx.rb +331 -0
- data/lib/rdx/assertions.rb +484 -0
- data/lib/rdx/binding.rb +151 -0
- data/lib/rdx/code_object.rb +598 -0
- data/lib/rdx/comment.rb +338 -0
- data/lib/rdx/convention.rb +1174 -0
- data/lib/rdx/directive.rb +1432 -0
- data/lib/rdx/example.rb +679 -0
- data/lib/rdx/generator.rb +112 -0
- data/lib/rdx/generator/rdoc.rb +1006 -0
- data/lib/rdx/options.rb +359 -0
- data/lib/rdx/plain_text.rb +65 -0
- data/lib/rdx/reporter.rb +421 -0
- data/lib/rdx/ruby_lex.rb +324 -0
- data/lib/rdx/runner.rb +309 -0
- data/lib/rdx/source_file.rb +94 -0
- data/lib/rdx/specification.rb +194 -0
- data/lib/rdx/statement.rb +248 -0
- data/lib/rdx/store.rb +119 -0
- data/lib/rdx/task.rb +361 -0
- data/lib/rdx/text.rb +688 -0
- data/lib/rdx/version.rb +15 -0
- data/rakefile +64 -0
- metadata +203 -0
@@ -0,0 +1,281 @@
|
|
1
|
+
--- core/orig/enum.c 2015-06-11 07:51:43 +0000
|
2
|
+
+++ core/patched/enum.c 2015-06-25 17:35:23 +0000
|
3
|
+
@@ -834,7 +834,9 @@
|
4
|
+
* call-seq:
|
5
|
+
* enum.sort_by { |obj| block } -> array
|
6
|
+
* enum.sort_by -> an_enumerator
|
7
|
+
- *
|
8
|
+
+ *
|
9
|
+
+ * :rdx: in_tmpdir!
|
10
|
+
+ *
|
11
|
+
* Sorts <i>enum</i> using a set of keys generated by mapping the
|
12
|
+
* values in <i>enum</i> through the given block.
|
13
|
+
*
|
14
|
+
@@ -848,6 +850,7 @@
|
15
|
+
* mapped value. This makes <code>sort_by</code> fairly expensive when
|
16
|
+
* the keysets are simple.
|
17
|
+
*
|
18
|
+
+ * :rdx: indicative_numbers
|
19
|
+
* require 'benchmark'
|
20
|
+
*
|
21
|
+
* a = (1..100000).map { rand(100000) }
|
22
|
+
@@ -857,15 +860,23 @@
|
23
|
+
* b.report("Sort by") { a.sort_by { |a| a } }
|
24
|
+
* end
|
25
|
+
*
|
26
|
+
- * <em>produces:</em>
|
27
|
+
+ * <em>On my machine produces:</em>
|
28
|
+
+ * :rdx: output
|
29
|
+
*
|
30
|
+
- * user system total real
|
31
|
+
+ * user system total real
|
32
|
+
* Sort 0.180000 0.000000 0.180000 ( 0.175469)
|
33
|
+
* Sort by 1.980000 0.040000 2.020000 ( 2.013586)
|
34
|
+
*
|
35
|
+
* However, consider the case where comparing the keys is a non-trivial
|
36
|
+
* operation. The following code sorts some files on modification time
|
37
|
+
* using the basic <code>sort</code> method.
|
38
|
+
+ *
|
39
|
+
+ *-- rdx
|
40
|
+
+ * %w[ mon tues wed thurs ].each_with_index do |fname,i|
|
41
|
+
+ * File.write fname, 'something'
|
42
|
+
+ * File.utime i, i, fname
|
43
|
+
+ * end
|
44
|
+
+ *++
|
45
|
+
*
|
46
|
+
* files = Dir["*"]
|
47
|
+
* sorted = files.sort { |a, b| File.new(a).mtime <=> File.new(b).mtime }
|
48
|
+
@@ -1693,7 +1704,7 @@
|
49
|
+
*
|
50
|
+
* (1..3).reverse_each { |v| p v }
|
51
|
+
*
|
52
|
+
- * produces:
|
53
|
+
+ * produces:
|
54
|
+
*
|
55
|
+
* 3
|
56
|
+
* 2
|
57
|
+
@@ -1805,7 +1816,9 @@
|
58
|
+
* block is given, returns an enumerator.
|
59
|
+
*
|
60
|
+
* (1..10).each_slice(3) { |a| p a }
|
61
|
+
- * # outputs below
|
62
|
+
+ *
|
63
|
+
+ * produces:
|
64
|
+
+ *
|
65
|
+
* [1, 2, 3]
|
66
|
+
* [4, 5, 6]
|
67
|
+
* [7, 8, 9]
|
68
|
+
@@ -1873,7 +1886,9 @@
|
69
|
+
*
|
70
|
+
* e.g.:
|
71
|
+
* (1..10).each_cons(3) { |a| p a }
|
72
|
+
- * # outputs below
|
73
|
+
+ *
|
74
|
+
+ * produces:
|
75
|
+
+ *
|
76
|
+
* [1, 2, 3]
|
77
|
+
* [2, 3, 4]
|
78
|
+
* [3, 4, 5]
|
79
|
+
@@ -2272,8 +2287,10 @@
|
80
|
+
* If no block is given, an enumerator is returned instead.
|
81
|
+
*
|
82
|
+
* a = ["a", "b", "c"]
|
83
|
+
- * a.cycle { |x| puts x } # print, a, b, c, a, b, c,.. forever.
|
84
|
+
- * a.cycle(2) { |x| puts x } # print, a, b, c, a, b, c.
|
85
|
+
+ * :rdx: off
|
86
|
+
+ * a.cycle { |x| print x } # prints abcabcabc... forever
|
87
|
+
+ * :rdx: on
|
88
|
+
+ * a.cycle(2) { |x| print x } # prints abcabc
|
89
|
+
*
|
90
|
+
*/
|
91
|
+
|
92
|
+
@@ -2405,26 +2422,35 @@
|
93
|
+
* [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5].chunk { |n|
|
94
|
+
* n.even?
|
95
|
+
* }.each { |even, ary|
|
96
|
+
- * p [even, ary]
|
97
|
+
+ * print [even, ary], "\n"
|
98
|
+
* }
|
99
|
+
- * #=> [false, [3, 1]]
|
100
|
+
- * # [true, [4]]
|
101
|
+
- * # [false, [1, 5, 9]]
|
102
|
+
- * # [true, [2, 6]]
|
103
|
+
- * # [false, [5, 3, 5]]
|
104
|
+
+ *
|
105
|
+
+ * produces:
|
106
|
+
+ *
|
107
|
+
+ * [false, [3, 1]]
|
108
|
+
+ * [true, [4]]
|
109
|
+
+ * [false, [1, 5, 9]]
|
110
|
+
+ * [true, [2, 6]]
|
111
|
+
+ * [false, [5, 3, 5]]
|
112
|
+
*
|
113
|
+
* This method is especially useful for sorted series of elements.
|
114
|
+
* The following example counts words for each initial letter.
|
115
|
+
- *
|
116
|
+
+ * :rdx: off
|
117
|
+
+ *
|
118
|
+
* open("/usr/share/dict/words", "r:iso-8859-1") { |f|
|
119
|
+
- * f.chunk { |line| line.ord }.each { |ch, lines| p [ch.chr, lines.length] }
|
120
|
+
+ * f.chunk { |line| line.ord }.each { |ch, lines| print [ch.chr, lines.length], "\n" }
|
121
|
+
* }
|
122
|
+
- * #=> ["\n", 1]
|
123
|
+
- * # ["A", 1327]
|
124
|
+
- * # ["B", 1372]
|
125
|
+
- * # ["C", 1507]
|
126
|
+
- * # ["D", 791]
|
127
|
+
- * # ...
|
128
|
+
+ *
|
129
|
+
+ * on my machine produces:
|
130
|
+
+ *
|
131
|
+
+ * ["\n", 1]
|
132
|
+
+ * ["A", 1327]
|
133
|
+
+ * ["B", 1372]
|
134
|
+
+ * ["C", 1507]
|
135
|
+
+ * ["D", 791]
|
136
|
+
+ * ...
|
137
|
+
+ *
|
138
|
+
+ * :rdx: on
|
139
|
+
*
|
140
|
+
* The following key values have special meaning:
|
141
|
+
* - +nil+ and +:_separator+ specifies that the elements should be dropped.
|
142
|
+
@@ -2432,33 +2458,39 @@
|
143
|
+
*
|
144
|
+
* Any other symbols that begin with an underscore will raise an error:
|
145
|
+
*
|
146
|
+
- * items.chunk { |item| :_underscore }
|
147
|
+
- * #=> RuntimeError: symbol begins with an underscore is reserved
|
148
|
+
+ * enum = [1,2,3].chunk { |item| :_underscore }
|
149
|
+
+ * enum.each{}
|
150
|
+
+ * # raises RuntimeError: symbol begins with an underscore is reserved
|
151
|
+
*
|
152
|
+
* +nil+ and +:_separator+ can be used to ignore some elements.
|
153
|
+
*
|
154
|
+
* For example, the sequence of hyphens in svn log can be eliminated as follows:
|
155
|
+
*
|
156
|
+
+ * :rdx: off
|
157
|
+
+ *
|
158
|
+
* sep = "-"*72 + "\n"
|
159
|
+
* IO.popen("svn log README") { |f|
|
160
|
+
* f.chunk { |line|
|
161
|
+
* line != sep || nil
|
162
|
+
* }.each { |_, lines|
|
163
|
+
- * pp lines
|
164
|
+
+ * puts lines
|
165
|
+
* }
|
166
|
+
* }
|
167
|
+
- * #=> ["r20018 | knu | 2008-10-29 13:20:42 +0900 (Wed, 29 Oct 2008) | 2 lines\n",
|
168
|
+
- * # "\n",
|
169
|
+
- * # "* README, README.ja: Update the portability section.\n",
|
170
|
+
- * # "\n"]
|
171
|
+
- * # ["r16725 | knu | 2008-05-31 23:34:23 +0900 (Sat, 31 May 2008) | 2 lines\n",
|
172
|
+
- * # "\n",
|
173
|
+
- * # "* README, README.ja: Add a note about default C flags.\n",
|
174
|
+
- * # "\n"]
|
175
|
+
- * # ...
|
176
|
+
+ *
|
177
|
+
+ * on my machine produces:
|
178
|
+
+ *
|
179
|
+
+ * r20018 | knu | 2008-10-29 13:20:42 +0900 (Wed, 29 Oct 2008) | 2 lines
|
180
|
+
+ *
|
181
|
+
+ * * README, README.ja: Update the portability section.
|
182
|
+
+ *
|
183
|
+
+ * r16725 | knu | 2008-05-31 23:34:23 +0900 (Sat, 31 May 2008) | 2 lines
|
184
|
+
+ *
|
185
|
+
+ * * README, README.ja: Add a note about default C flags
|
186
|
+
+ *
|
187
|
+
+ * ...
|
188
|
+
*
|
189
|
+
* Paragraphs separated by empty lines can be parsed as follows:
|
190
|
+
- *
|
191
|
+
+ *
|
192
|
+
* File.foreach("README").chunk { |line|
|
193
|
+
* /\A\s*\z/ !~ line || nil
|
194
|
+
* }.each { |_, lines|
|
195
|
+
@@ -2582,6 +2614,7 @@
|
196
|
+
* The result enumerator yields the chunked elements as an array.
|
197
|
+
* So +each+ method can be called as follows:
|
198
|
+
*
|
199
|
+
+ * :rdx: off -
|
200
|
+
* enum.slice_before(pattern).each { |ary| ... }
|
201
|
+
* enum.slice_before { |elt| bool }.each { |ary| ... }
|
202
|
+
* enum.slice_before(initial_state) { |elt, state| bool }.each { |ary| ... }
|
203
|
+
@@ -2591,6 +2624,8 @@
|
204
|
+
*
|
205
|
+
* For example, iteration over ChangeLog entries can be implemented as
|
206
|
+
* follows:
|
207
|
+
+ *
|
208
|
+
+ * :rdx: off
|
209
|
+
*
|
210
|
+
* # iterate over ChangeLog entries.
|
211
|
+
* open("ChangeLog") { |f|
|
212
|
+
@@ -2602,27 +2637,31 @@
|
213
|
+
* f.slice_before { |line| /\A\S/ === line }.each { |e| pp e }
|
214
|
+
* }
|
215
|
+
*
|
216
|
+
- *
|
217
|
+
* "svn proplist -R" produces multiline output for each file.
|
218
|
+
* They can be chunked as follows:
|
219
|
+
*
|
220
|
+
* IO.popen([{"LC_ALL"=>"C"}, "svn", "proplist", "-R"]) { |f|
|
221
|
+
- * f.lines.slice_before(/\AProp/).each { |lines| p lines }
|
222
|
+
+ * f.lines.slice_before(/\AProp/).each { |lines| print lines, "\n" }
|
223
|
+
* }
|
224
|
+
- * #=> ["Properties on '.':\n", " svn:ignore\n", " svk:merge\n"]
|
225
|
+
- * # ["Properties on 'goruby.c':\n", " svn:eol-style\n"]
|
226
|
+
- * # ["Properties on 'complex.c':\n", " svn:mime-type\n", " svn:eol-style\n"]
|
227
|
+
- * # ["Properties on 'regparse.c':\n", " svn:eol-style\n"]
|
228
|
+
- * # ...
|
229
|
+
+ *
|
230
|
+
+ * on my machine produces:
|
231
|
+
+ *
|
232
|
+
+ * ["Properties on '.':\n", " svn:ignore\n", " svk:merge\n"]
|
233
|
+
+ * ["Properties on 'goruby.c':\n", " svn:eol-style\n"]
|
234
|
+
+ * ["Properties on 'complex.c':\n", " svn:mime-type\n", " svn:eol-style\n"]
|
235
|
+
+ * ["Properties on 'regparse.c':\n", " svn:eol-style\n"]
|
236
|
+
+ * ...
|
237
|
+
*
|
238
|
+
* If the block needs to maintain state over multiple elements,
|
239
|
+
* local variables can be used.
|
240
|
+
* For example, three or more consecutive increasing numbers can be squashed
|
241
|
+
* as follows:
|
242
|
+
+ *
|
243
|
+
+ * :rdx: on
|
244
|
+
*
|
245
|
+
* a = [0, 2, 3, 4, 6, 7, 9]
|
246
|
+
* prev = a[0]
|
247
|
+
- * p a.slice_before { |e|
|
248
|
+
+ * a.slice_before { |e|
|
249
|
+
* prev, prev2 = e, prev
|
250
|
+
* prev2 + 1 != e
|
251
|
+
* }.map { |es|
|
252
|
+
@@ -2658,18 +2697,21 @@
|
253
|
+
* puts "-"*10
|
254
|
+
* enum.each { |ws| puts ws.join(" ") }
|
255
|
+
* puts "-"*10
|
256
|
+
- * #=> ----------
|
257
|
+
- * # 1 2 3 4 5
|
258
|
+
- * # 6 7 8 9 10
|
259
|
+
- * # 11 12 13
|
260
|
+
- * # 14 15 16
|
261
|
+
- * # 17 18 19
|
262
|
+
- * # 20
|
263
|
+
- * # ----------
|
264
|
+
+ * produces:
|
265
|
+
+ * ----------
|
266
|
+
+ * 1 2 3 4 5
|
267
|
+
+ * 6 7 8 9 10
|
268
|
+
+ * 11 12 13
|
269
|
+
+ * 14 15 16
|
270
|
+
+ * 17 18 19
|
271
|
+
+ * 20
|
272
|
+
+ * ----------
|
273
|
+
*
|
274
|
+
* mbox contains series of mails which start with Unix From line.
|
275
|
+
* So each mail can be extracted by slice before Unix From line.
|
276
|
+
*
|
277
|
+
+ * :rdx: off
|
278
|
+
+ *
|
279
|
+
* # parse mbox
|
280
|
+
* open("mbox") { |f|
|
281
|
+
* f.slice_before { |line|
|
@@ -0,0 +1,479 @@
|
|
1
|
+
--- core/orig/enumerator.c 2015-06-11 07:51:44 +0000
|
2
|
+
+++ core/patched/enumerator.c 2015-06-20 08:06:24 +0000
|
3
|
+
@@ -26,51 +26,80 @@
|
4
|
+
* - Kernel#enum_for
|
5
|
+
* - Enumerator.new
|
6
|
+
*
|
7
|
+
- * Most methods have two forms: a block form where the contents
|
8
|
+
- * are evaluated for each item in the enumeration, and a non-block form
|
9
|
+
- * which returns a new Enumerator wrapping the iteration.
|
10
|
+
+ * Most methods have two forms:
|
11
|
+
+ * * a block form where the contents are evaluated
|
12
|
+
+ * for each item in the enumeration:
|
13
|
+
*
|
14
|
+
- * enumerator = %w(one two three).each
|
15
|
+
- * puts enumerator.class # => Enumerator
|
16
|
+
+ * enumerator = %w(one two three).each
|
17
|
+
+ * enumerator.class # => Enumerator
|
18
|
+
*
|
19
|
+
- * enumerator.each_with_object("foo") do |item, obj|
|
20
|
+
- * puts "#{obj}: #{item}"
|
21
|
+
- * end
|
22
|
+
- *
|
23
|
+
- * # foo: one
|
24
|
+
- * # foo: two
|
25
|
+
- * # foo: three
|
26
|
+
+ * enumerator.each_with_object("foo") do |item, obj|
|
27
|
+
+ * puts "#{obj}: #{item}"
|
28
|
+
+ * end
|
29
|
+
+ *
|
30
|
+
+ * produces:
|
31
|
+
*
|
32
|
+
- * enum_with_obj = enumerator.each_with_object("foo")
|
33
|
+
- * puts enum_with_obj.class # => Enumerator
|
34
|
+
+ * foo: one
|
35
|
+
+ * foo: two
|
36
|
+
+ * foo: three
|
37
|
+
+ *
|
38
|
+
+ * * a non-block form which returns a new Enumerator
|
39
|
+
+ * wrapping the iteration:
|
40
|
+
+ *
|
41
|
+
+ * enum_with_obj = enumerator.each_with_object("foo")
|
42
|
+
+ * enum_with_obj.class # => Enumerator
|
43
|
+
*
|
44
|
+
- * enum_with_obj.each do |item, obj|
|
45
|
+
- * puts "#{obj}: #{item}"
|
46
|
+
- * end
|
47
|
+
+ * enum_with_obj.each do |item, obj|
|
48
|
+
+ * puts "#{obj}: #{item}"
|
49
|
+
+ * end
|
50
|
+
*
|
51
|
+
- * # foo: one
|
52
|
+
- * # foo: two
|
53
|
+
- * # foo: three
|
54
|
+
+ * produces:
|
55
|
+
+ *
|
56
|
+
+ * foo: one
|
57
|
+
+ * foo: two
|
58
|
+
+ * foo: three
|
59
|
+
*
|
60
|
+
* This allows you to chain Enumerators together. For example, you
|
61
|
+
* can map a list's elements to strings containing the index
|
62
|
+
* and the element as a string via:
|
63
|
+
*
|
64
|
+
- * puts %w[foo bar baz].map.with_index { |w, i| "#{i}:#{w}" }
|
65
|
+
+ * %w[foo bar baz].map.with_index { |w, i| "#{i}:#{w}" }
|
66
|
+
* # => ["0:foo", "1:bar", "2:baz"]
|
67
|
+
*
|
68
|
+
* An Enumerator can also be used as an external iterator.
|
69
|
+
* For example, Enumerator#next returns the next value of the iterator
|
70
|
+
* or raises StopIteration if the Enumerator is at the end.
|
71
|
+
*
|
72
|
+
- * e = [1,2,3].each # returns an enumerator object.
|
73
|
+
- * puts e.next # => 1
|
74
|
+
- * puts e.next # => 2
|
75
|
+
- * puts e.next # => 3
|
76
|
+
- * puts e.next # raises StopIteration
|
77
|
+
+ * e = [1,2,3].each # > #<Enumerator: [1, 2, 3]:each>
|
78
|
+
+ * e.next # => 1
|
79
|
+
+ * e.next # => 2
|
80
|
+
+ * e.next # => 3
|
81
|
+
+ * e.next # raises StopIteration
|
82
|
+
*
|
83
|
+
* You can use this to implement an internal iterator as follows:
|
84
|
+
*
|
85
|
+
+ * o = Object.new
|
86
|
+
+ *
|
87
|
+
+ * def o.each
|
88
|
+
+ * yield
|
89
|
+
+ * yield(1)
|
90
|
+
+ * yield(1, 2)
|
91
|
+
+ * 3
|
92
|
+
+ * end
|
93
|
+
+ *
|
94
|
+
+ * Use o.each as an internal iterator directly:
|
95
|
+
+ *
|
96
|
+
+ * o.each {|*x| print x, "\n" } #=> 3
|
97
|
+
+ * # puts would have expanded the arrays
|
98
|
+
+ *
|
99
|
+
+ * produces:
|
100
|
+
+ *
|
101
|
+
+ * []
|
102
|
+
+ * [1]
|
103
|
+
+ * [1, 2]
|
104
|
+
+ *
|
105
|
+
+ * Or convert an internal iterator to an external one:
|
106
|
+
+ *
|
107
|
+
* def ext_each(e)
|
108
|
+
* while true
|
109
|
+
* begin
|
110
|
+
@@ -82,24 +111,16 @@
|
111
|
+
* e.feed y
|
112
|
+
* end
|
113
|
+
* end
|
114
|
+
- *
|
115
|
+
- * o = Object.new
|
116
|
+
- *
|
117
|
+
- * def o.each
|
118
|
+
- * puts yield
|
119
|
+
- * puts yield(1)
|
120
|
+
- * puts yield(1, 2)
|
121
|
+
- * 3
|
122
|
+
- * end
|
123
|
+
- *
|
124
|
+
- * # use o.each as an internal iterator directly.
|
125
|
+
- * puts o.each {|*x| puts x; [:b, *x] }
|
126
|
+
- * # => [], [:b], [1], [:b, 1], [1, 2], [:b, 1, 2], 3
|
127
|
+
- *
|
128
|
+
+ *
|
129
|
+
* # convert o.each to an external iterator for
|
130
|
+
* # implementing an internal iterator.
|
131
|
+
- * puts ext_each(o.to_enum) {|*x| puts x; [:b, *x] }
|
132
|
+
- * # => [], [:b], [1], [:b, 1], [1, 2], [:b, 1, 2], 3
|
133
|
+
+ * ext_each(o.to_enum) {|*x| print x, "\n" } #=> 3
|
134
|
+
+ *
|
135
|
+
+ * produces:
|
136
|
+
+ *
|
137
|
+
+ * []
|
138
|
+
+ * [1]
|
139
|
+
+ * [1, 2]
|
140
|
+
*
|
141
|
+
*/
|
142
|
+
VALUE rb_cEnumerator;
|
143
|
+
@@ -197,23 +218,34 @@
|
144
|
+
*
|
145
|
+
* === Examples
|
146
|
+
*
|
147
|
+
+ * Iterating over a string:
|
148
|
+
* str = "xyz"
|
149
|
+
*
|
150
|
+
* enum = str.enum_for(:each_byte)
|
151
|
+
* enum.each { |b| puts b }
|
152
|
+
- * # => 120
|
153
|
+
- * # => 121
|
154
|
+
- * # => 122
|
155
|
+
- *
|
156
|
+
- * # protect an array from being modified by some_method
|
157
|
+
+ * produces:
|
158
|
+
+ * 120
|
159
|
+
+ * 121
|
160
|
+
+ * 122
|
161
|
+
+ *
|
162
|
+
+ * Protect an array from being modified (an enumerator doesn't respond to destructive methods):
|
163
|
+
+ * def some_method ary
|
164
|
+
+ * ary.each{ |x| } # do something...
|
165
|
+
+ * ary.clear
|
166
|
+
+ * end
|
167
|
+
* a = [1, 2, 3]
|
168
|
+
- * some_method(a.to_enum)
|
169
|
+
+ * some_method(a)
|
170
|
+
+ * a #=> []
|
171
|
+
+ * e = [1, 2, 3].to_enum
|
172
|
+
+ * some_method(e) # raises NoMethodError
|
173
|
+
*
|
174
|
+
* It is typical to call to_enum when defining methods for
|
175
|
+
* a generic Enumerable, in case no block is passed.
|
176
|
+
*
|
177
|
+
* Here is such an example, with parameter passing and a sizing block:
|
178
|
+
*
|
179
|
+
+ * :rdx: toplevel
|
180
|
+
+ *
|
181
|
+
* module Enumerable
|
182
|
+
* # a generic method to repeat the values of any enumerable
|
183
|
+
* def repeat(n)
|
184
|
+
@@ -230,10 +262,11 @@
|
185
|
+
* end
|
186
|
+
* end
|
187
|
+
*
|
188
|
+
- * %i[hello world].repeat(2) { |w| puts w }
|
189
|
+
- * # => Prints 'hello', 'hello', 'world', 'world'
|
190
|
+
+ * %i[hello world].repeat(2) { |w| print w, ' ' }
|
191
|
+
+ * # Prints: hello hello world world
|
192
|
+
+ *
|
193
|
+
* enum = (1..14).repeat(3)
|
194
|
+
- * # => returns an Enumerator when called without a block
|
195
|
+
+ * # returns an Enumerator when called without a block
|
196
|
+
* enum.first(4) # => [1, 1, 1, 2]
|
197
|
+
* enum.size # => 42
|
198
|
+
*/
|
199
|
+
@@ -310,7 +343,7 @@
|
200
|
+
* end
|
201
|
+
* end
|
202
|
+
*
|
203
|
+
- * p fib.take(10) # => [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
|
204
|
+
+ * fib.take(10) # => [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
|
205
|
+
*
|
206
|
+
* The optional parameter can be used to specify how to calculate the size
|
207
|
+
* in a lazy fashion (see Enumerator#size). It can either be a value or
|
208
|
+
@@ -325,7 +358,19 @@
|
209
|
+
* e = Enumerator.new(ObjectSpace, :each_object)
|
210
|
+
* #-> ObjectSpace.enum_for(:each_object)
|
211
|
+
*
|
212
|
+
- * e.select { |obj| obj.is_a?(Class) } #=> array of all classes
|
213
|
+
+ * produces on stderr:
|
214
|
+
+ * :rdx: stderr
|
215
|
+
+ *
|
216
|
+
+ * warning: Enumerator.new without a block is deprecated; use Object#to_enum
|
217
|
+
+ *
|
218
|
+
+ * However it's still usable:
|
219
|
+
+ *
|
220
|
+
+ * e.select { |obj| obj.is_a?(Class) }
|
221
|
+
+ * # -> [
|
222
|
+
+ * # Class, Module, Object, Numeric, String,
|
223
|
+
+ * # # ... all other classes
|
224
|
+
+ * # ]
|
225
|
+
+ *
|
226
|
+
*
|
227
|
+
*/
|
228
|
+
static VALUE
|
229
|
+
@@ -545,10 +590,12 @@
|
230
|
+
* to_three_with_string.each do |x,string|
|
231
|
+
* puts "#{string}: #{x}"
|
232
|
+
* end
|
233
|
+
+ *
|
234
|
+
+ * produces:
|
235
|
+
*
|
236
|
+
- * # => foo:0
|
237
|
+
- * # => foo:1
|
238
|
+
- * # => foo:2
|
239
|
+
+ * foo: 0
|
240
|
+
+ * foo: 1
|
241
|
+
+ * foo: 2
|
242
|
+
*/
|
243
|
+
static VALUE
|
244
|
+
enumerator_with_object(VALUE obj, VALUE memo)
|
245
|
+
@@ -641,25 +688,29 @@
|
246
|
+
* yield nil
|
247
|
+
* yield [1, 2]
|
248
|
+
* end
|
249
|
+
- * e = o.to_enum
|
250
|
+
- * p e.next_values
|
251
|
+
- * p e.next_values
|
252
|
+
- * p e.next_values
|
253
|
+
- * p e.next_values
|
254
|
+
- * p e.next_values
|
255
|
+
- * e = o.to_enum
|
256
|
+
- * p e.next
|
257
|
+
- * p e.next
|
258
|
+
- * p e.next
|
259
|
+
- * p e.next
|
260
|
+
- * p e.next
|
261
|
+
- *
|
262
|
+
- * ## yield args next_values next
|
263
|
+
- * # yield [] nil
|
264
|
+
- * # yield 1 [1] 1
|
265
|
+
- * # yield 1, 2 [1, 2] [1, 2]
|
266
|
+
- * # yield nil [nil] nil
|
267
|
+
- * # yield [1, 2] [[1, 2]] [1, 2]
|
268
|
+
+ *
|
269
|
+
+ * e1 = o.to_enum
|
270
|
+
+ * e2 = o.to_enum
|
271
|
+
+ *
|
272
|
+
+ * # yield
|
273
|
+
+ * e1.next_values #=> []
|
274
|
+
+ * e2.next #=> nil
|
275
|
+
+ *
|
276
|
+
+ * # yield 1
|
277
|
+
+ * e1.next_values #=> [1]
|
278
|
+
+ * e2.next #=> 1
|
279
|
+
+ *
|
280
|
+
+ * # yield 1, 2
|
281
|
+
+ * e1.next_values #=> [1, 2]
|
282
|
+
+ * e2.next #=> [1, 2]
|
283
|
+
+ *
|
284
|
+
+ * # yield nil
|
285
|
+
+ * e1.next_values #=> [nil]
|
286
|
+
+ * e2.next #=> nil
|
287
|
+
+ *
|
288
|
+
+ * # yield [1, 2]
|
289
|
+
+ * e1.next_values #=> [[1, 2]]
|
290
|
+
+ * e2.next #=> [1, 2]
|
291
|
+
*
|
292
|
+
* Note that +next_values+ does not affect other non-external enumeration
|
293
|
+
* methods unless underlying iteration method itself has side-effect, e.g.
|
294
|
+
@@ -713,10 +764,10 @@
|
295
|
+
*
|
296
|
+
* a = [1,2,3]
|
297
|
+
* e = a.to_enum
|
298
|
+
- * p e.next #=> 1
|
299
|
+
- * p e.next #=> 2
|
300
|
+
- * p e.next #=> 3
|
301
|
+
- * p e.next #raises StopIteration
|
302
|
+
+ * e.next #=> 1
|
303
|
+
+ * e.next #=> 2
|
304
|
+
+ * e.next #=> 3
|
305
|
+
+ * e.next #raises StopIteration
|
306
|
+
*
|
307
|
+
* Note that enumeration sequence by +next+ does not affect other non-external
|
308
|
+
* enumeration methods, unless the underlying iteration methods itself has
|
309
|
+
@@ -759,14 +810,14 @@
|
310
|
+
* yield 1, 2
|
311
|
+
* end
|
312
|
+
* e = o.to_enum
|
313
|
+
- * p e.peek_values #=> []
|
314
|
+
+ * e.peek_values #=> []
|
315
|
+
* e.next
|
316
|
+
- * p e.peek_values #=> [1]
|
317
|
+
- * p e.peek_values #=> [1]
|
318
|
+
+ * e.peek_values #=> [1]
|
319
|
+
+ * e.peek_values #=> [1]
|
320
|
+
* e.next
|
321
|
+
- * p e.peek_values #=> [1, 2]
|
322
|
+
+ * e.peek_values #=> [1, 2]
|
323
|
+
* e.next
|
324
|
+
- * p e.peek_values # raises StopIteration
|
325
|
+
+ * e.peek_values # raises StopIteration
|
326
|
+
*
|
327
|
+
*/
|
328
|
+
|
329
|
+
@@ -788,13 +839,13 @@
|
330
|
+
*
|
331
|
+
* a = [1,2,3]
|
332
|
+
* e = a.to_enum
|
333
|
+
- * p e.next #=> 1
|
334
|
+
- * p e.peek #=> 2
|
335
|
+
- * p e.peek #=> 2
|
336
|
+
- * p e.peek #=> 2
|
337
|
+
- * p e.next #=> 2
|
338
|
+
- * p e.next #=> 3
|
339
|
+
- * p e.next #raises StopIteration
|
340
|
+
+ * e.next #=> 1
|
341
|
+
+ * e.peek #=> 2
|
342
|
+
+ * e.peek #=> 2
|
343
|
+
+ * e.peek #=> 2
|
344
|
+
+ * e.next #=> 2
|
345
|
+
+ * e.next #=> 3
|
346
|
+
+ * e.next #raises StopIteration
|
347
|
+
*
|
348
|
+
*/
|
349
|
+
|
350
|
+
@@ -815,22 +866,27 @@
|
351
|
+
*
|
352
|
+
* This value is cleared after being yielded.
|
353
|
+
*
|
354
|
+
+ * :rdx: no_warnings eval
|
355
|
+
* o = Object.new
|
356
|
+
* def o.each
|
357
|
+
- * x = yield # (2) blocks
|
358
|
+
- * p x # (5) => "foo"
|
359
|
+
- * x = yield # (6) blocks
|
360
|
+
- * p x # (8) => nil
|
361
|
+
- * x = yield # (9) blocks
|
362
|
+
+ * x = yield # (2) blocks
|
363
|
+
+ * p x # (5) x == "foo"
|
364
|
+
+ * x = yield # (6) blocks
|
365
|
+
+ * p x # (9) x == nil
|
366
|
+
+ * x = yield # (10) blocks
|
367
|
+
* p x # not reached w/o another e.next
|
368
|
+
* end
|
369
|
+
- *
|
370
|
+
* e = o.to_enum
|
371
|
+
+ *
|
372
|
+
* e.next # (1)
|
373
|
+
* e.feed "foo" # (3)
|
374
|
+
- * e.next # (4)
|
375
|
+
- * e.next # (7)
|
376
|
+
- * # (10)
|
377
|
+
+ * # (4) next call
|
378
|
+
+ * e.next # prints: "foo"
|
379
|
+
+ * # (7) next returns
|
380
|
+
+ * # (8) next call
|
381
|
+
+ * e.next # prints: nil
|
382
|
+
+ * # (11) next return
|
383
|
+
+ *
|
384
|
+
*/
|
385
|
+
|
386
|
+
static VALUE
|
387
|
+
@@ -964,7 +1020,7 @@
|
388
|
+
* Returns the size of the enumerator, or +nil+ if it can't be calculated lazily.
|
389
|
+
*
|
390
|
+
* (1..100).to_a.permutation(4).size # => 94109400
|
391
|
+
- * loop.size # => Float::INFINITY
|
392
|
+
+ * loop.size # > Infinity
|
393
|
+
* (1..100).drop_while.size # => nil
|
394
|
+
*/
|
395
|
+
|
396
|
+
@@ -1354,6 +1410,7 @@
|
397
|
+
* === Example
|
398
|
+
*
|
399
|
+
* The following program finds pythagorean triples:
|
400
|
+
+ * :rdx: discard_output
|
401
|
+
*
|
402
|
+
* def pythagorean_triples
|
403
|
+
* (1..Float::INFINITY).lazy.flat_map {|z|
|
404
|
+
@@ -1366,6 +1423,7 @@
|
405
|
+
* }
|
406
|
+
* }
|
407
|
+
* end
|
408
|
+
+ *
|
409
|
+
* # show first ten pythagorean triples
|
410
|
+
* p pythagorean_triples.take(10).force # take is lazy, so force is needed
|
411
|
+
* p pythagorean_triples.first(10) # first is eager
|
412
|
+
@@ -1400,12 +1458,31 @@
|
413
|
+
* naturally remain lazy if called from a lazy enumerator.
|
414
|
+
*
|
415
|
+
* For example, continuing from the example in Kernel#to_enum:
|
416
|
+
- *
|
417
|
+
+ *
|
418
|
+
* # See Kernel#to_enum for the definition of repeat
|
419
|
+
+ *-- rdx
|
420
|
+
+ * module ::Enumerable
|
421
|
+
+ * # a generic method to repeat the values of any enumerable
|
422
|
+
+ * def repeat(n)
|
423
|
+
+ * raise ArgumentError, "#{n} is negative!" if n < 0
|
424
|
+
+ * unless block_given?
|
425
|
+
+ * return to_enum(__method__, n) do # __method__ is :repeat here
|
426
|
+
+ * sz = size # Call size and multiply by n...
|
427
|
+
+ * sz * n if sz # but return nil if size itself is nil
|
428
|
+
+ * end
|
429
|
+
+ * end
|
430
|
+
+ * each do |*val|
|
431
|
+
+ * n.times { yield *val }
|
432
|
+
+ * end
|
433
|
+
+ * end
|
434
|
+
+ * end
|
435
|
+
+ *++
|
436
|
+
* r = 1..Float::INFINITY
|
437
|
+
* r.repeat(2).first(5) # => [1, 1, 2, 2, 3]
|
438
|
+
* r.repeat(2).class # => Enumerator
|
439
|
+
- * r.repeat(2).map{|n| n ** 2}.first(5) # => endless loop!
|
440
|
+
+ * :rdx: off
|
441
|
+
+ * r.repeat(2).map{|n| n ** 2}.first(5) # endless loop!
|
442
|
+
+ * :rdx:
|
443
|
+
* # works naturally on lazy enumerator:
|
444
|
+
* r.lazy.repeat(2).class # => Enumerator::Lazy
|
445
|
+
* r.lazy.repeat(2).map{|n| n ** 2}.first(5) # => [1, 1, 4, 4, 9]
|
446
|
+
@@ -1511,9 +1588,9 @@
|
447
|
+
* A value <i>x</i> returned by <i>block</i> is decomposed if either of
|
448
|
+
* the following conditions is true:
|
449
|
+
*
|
450
|
+
- * a) <i>x</i> responds to both each and force, which means that
|
451
|
+
- * <i>x</i> is a lazy enumerator.
|
452
|
+
- * b) <i>x</i> is an array or responds to to_ary.
|
453
|
+
+ * * <i>x</i> responds to both each and force, which means that
|
454
|
+
+ * <i>x</i> is a lazy enumerator.
|
455
|
+
+ * * <i>x</i> is an array or responds to to_ary.
|
456
|
+
*
|
457
|
+
* Otherwise, <i>x</i> is contained as-is in the return value.
|
458
|
+
*
|
459
|
+
@@ -1888,15 +1965,15 @@
|
460
|
+
*
|
461
|
+
* e = o.to_enum
|
462
|
+
*
|
463
|
+
- * puts e.next #=> 1
|
464
|
+
- * puts e.next #=> 2
|
465
|
+
- * puts e.next #=> 3
|
466
|
+
+ * e.next #=> 1
|
467
|
+
+ * e.next #=> 2
|
468
|
+
+ * e.next #=> 3
|
469
|
+
*
|
470
|
+
* begin
|
471
|
+
* e.next
|
472
|
+
* rescue StopIteration => ex
|
473
|
+
- * puts ex.result #=> 100
|
474
|
+
- * end
|
475
|
+
+ * ex.result
|
476
|
+
+ * end #=> 100
|
477
|
+
*
|
478
|
+
*/
|
479
|
+
|