Ruby  2.0.0p353(2013-11-22revision43784)
enum.c
Go to the documentation of this file.
1 /**********************************************************************
2 
3  enum.c -
4 
5  $Author: zzak $
6  created at: Fri Oct 1 15:15:19 JST 1993
7 
8  Copyright (C) 1993-2007 Yukihiro Matsumoto
9 
10 **********************************************************************/
11 
12 #include "ruby/ruby.h"
13 #include "ruby/util.h"
14 #include "node.h"
15 #include "id.h"
16 #include "internal.h"
17 
18 #define STATIC_ASSERT(name, expr) typedef int static_assert_##name##_check[1 - 2*!(expr)]
19 
21 
22 static ID id_next;
23 static ID id_div;
24 static ID id_call;
25 static ID id_size;
26 
27 #define id_each idEach
28 #define id_eqq idEqq
29 #define id_cmp idCmp
30 #define id_lshift idLTLT
31 
32 VALUE
34 {
35  if (argc == 0) return Qnil;
36  if (argc == 1) return argv[0];
37  return rb_ary_new4(argc, argv);
38 }
39 
40 #define ENUM_WANT_SVALUE() do { \
41  i = rb_enum_values_pack(argc, argv); \
42 } while (0)
43 
44 #define enum_yield rb_yield_values2
45 
46 static VALUE
48 {
49  NODE *memo = RNODE(args);
51 
52  if (RTEST(rb_funcall(memo->u1.value, id_eqq, 1, i))) {
53  rb_ary_push(memo->u2.value, i);
54  }
55  return Qnil;
56 }
57 
58 static VALUE
60 {
61  NODE *memo = RNODE(args);
63 
64  if (RTEST(rb_funcall(memo->u1.value, id_eqq, 1, i))) {
65  rb_ary_push(memo->u2.value, rb_yield(i));
66  }
67  return Qnil;
68 }
69 
70 /*
71  * call-seq:
72  * enum.grep(pattern) -> array
73  * enum.grep(pattern) { |obj| block } -> array
74  *
75  * Returns an array of every element in <i>enum</i> for which
76  * <code>Pattern === element</code>. If the optional <em>block</em> is
77  * supplied, each matching element is passed to it, and the block's
78  * result is stored in the output array.
79  *
80  * (1..100).grep 38..44 #=> [38, 39, 40, 41, 42, 43, 44]
81  * c = IO.constants
82  * c.grep(/SEEK/) #=> [:SEEK_SET, :SEEK_CUR, :SEEK_END]
83  * res = c.grep(/SEEK/) { |v| IO.const_get(v) }
84  * res #=> [0, 1, 2]
85  *
86  */
87 
88 static VALUE
90 {
91  VALUE ary = rb_ary_new();
92  NODE *memo = NEW_MEMO(pat, ary, 0);
93 
95 
96  return ary;
97 }
98 
99 static VALUE
101 {
102  NODE *memo = RNODE(memop);
103 
105 
106  if (rb_equal(i, memo->u1.value)) {
107  memo->u3.cnt++;
108  }
109  return Qnil;
110 }
111 
112 static VALUE
114 {
115  NODE *memo = RNODE(memop);
116 
117  if (RTEST(enum_yield(argc, argv))) {
118  memo->u3.cnt++;
119  }
120  return Qnil;
121 }
122 
123 static VALUE
125 {
126  NODE *memo = RNODE(memop);
127 
128  memo->u3.cnt++;
129  return Qnil;
130 }
131 
132 /*
133  * call-seq:
134  * enum.count -> int
135  * enum.count(item) -> int
136  * enum.count { |obj| block } -> int
137  *
138  * Returns the number of items in +enum+ through enumeration.
139  * If an argument is given, the number of items in +enum+ that
140  * are equal to +item+ are counted. If a block is given, it
141  * counts the number of elements yielding a true value.
142  *
143  * ary = [1, 2, 4, 2]
144  * ary.count #=> 4
145  * ary.count(2) #=> 2
146  * ary.count{ |x| x%2==0 } #=> 3
147  *
148  */
149 
150 static VALUE
152 {
153  VALUE item = Qnil;
154  NODE *memo;
156 
157  if (argc == 0) {
158  if (rb_block_given_p()) {
159  func = count_iter_i;
160  }
161  else {
162  func = count_all_i;
163  }
164  }
165  else {
166  rb_scan_args(argc, argv, "1", &item);
167  if (rb_block_given_p()) {
168  rb_warn("given block not used");
169  }
170  func = count_i;
171  }
172 
173  memo = NEW_MEMO(item, 0, 0);
174  rb_block_call(obj, id_each, 0, 0, func, (VALUE)memo);
175  return INT2NUM(memo->u3.cnt);
176 }
177 
178 static VALUE
179 find_i(VALUE i, VALUE memop, int argc, VALUE *argv)
180 {
182 
183  if (RTEST(rb_yield(i))) {
184  NODE *memo = RNODE(memop);
185  memo->u1.value = i;
186  memo->u3.cnt = 1;
187  rb_iter_break();
188  }
189  return Qnil;
190 }
191 
192 /*
193  * call-seq:
194  * enum.detect(ifnone = nil) { |obj| block } -> obj or nil
195  * enum.find(ifnone = nil) { |obj| block } -> obj or nil
196  * enum.detect(ifnone = nil) -> an_enumerator
197  * enum.find(ifnone = nil) -> an_enumerator
198  *
199  * Passes each entry in <i>enum</i> to <em>block</em>. Returns the
200  * first for which <em>block</em> is not false. If no
201  * object matches, calls <i>ifnone</i> and returns its result when it
202  * is specified, or returns <code>nil</code> otherwise.
203  *
204  * If no block is given, an enumerator is returned instead.
205  *
206  * (1..10).detect { |i| i % 5 == 0 and i % 7 == 0 } #=> nil
207  * (1..100).detect { |i| i % 5 == 0 and i % 7 == 0 } #=> 35
208  *
209  */
210 
211 static VALUE
213 {
214  NODE *memo;
215  VALUE if_none;
216 
217  rb_scan_args(argc, argv, "01", &if_none);
218  RETURN_ENUMERATOR(obj, argc, argv);
219  memo = NEW_MEMO(Qundef, 0, 0);
220  rb_block_call(obj, id_each, 0, 0, find_i, (VALUE)memo);
221  if (memo->u3.cnt) {
222  return memo->u1.value;
223  }
224  if (!NIL_P(if_none)) {
225  return rb_funcall(if_none, id_call, 0, 0);
226  }
227  return Qnil;
228 }
229 
230 static VALUE
232 {
233  NODE *memo = RNODE(memop);
234 
236 
237  if (rb_equal(i, memo->u2.value)) {
238  memo->u1.value = UINT2NUM(memo->u3.cnt);
239  rb_iter_break();
240  }
241  memo->u3.cnt++;
242  return Qnil;
243 }
244 
245 static VALUE
247 {
248  NODE *memo = RNODE(memop);
249 
250  if (RTEST(enum_yield(argc, argv))) {
251  memo->u1.value = UINT2NUM(memo->u3.cnt);
252  rb_iter_break();
253  }
254  memo->u3.cnt++;
255  return Qnil;
256 }
257 
258 /*
259  * call-seq:
260  * enum.find_index(value) -> int or nil
261  * enum.find_index { |obj| block } -> int or nil
262  * enum.find_index -> an_enumerator
263  *
264  * Compares each entry in <i>enum</i> with <em>value</em> or passes
265  * to <em>block</em>. Returns the index for the first for which the
266  * evaluated value is non-false. If no object matches, returns
267  * <code>nil</code>
268  *
269  * If neither block nor argument is given, an enumerator is returned instead.
270  *
271  * (1..10).find_index { |i| i % 5 == 0 and i % 7 == 0 } #=> nil
272  * (1..100).find_index { |i| i % 5 == 0 and i % 7 == 0 } #=> 34
273  * (1..100).find_index(50) #=> 49
274  *
275  */
276 
277 static VALUE
279 {
280  NODE *memo; /* [return value, current index, ] */
281  VALUE condition_value = Qnil;
283 
284  if (argc == 0) {
285  RETURN_ENUMERATOR(obj, 0, 0);
286  func = find_index_iter_i;
287  }
288  else {
289  rb_scan_args(argc, argv, "1", &condition_value);
290  if (rb_block_given_p()) {
291  rb_warn("given block not used");
292  }
293  func = find_index_i;
294  }
295 
296  memo = NEW_MEMO(Qnil, condition_value, 0);
297  rb_block_call(obj, id_each, 0, 0, func, (VALUE)memo);
298  return memo->u1.value;
299 }
300 
301 static VALUE
303 {
305 
306  if (RTEST(rb_yield(i))) {
307  rb_ary_push(ary, i);
308  }
309  return Qnil;
310 }
311 
312 static VALUE
314 {
315  VALUE r;
316  r = rb_check_funcall(self, id_size, 0, 0);
317  return (r == Qundef) ? Qnil : r;
318 }
319 
320 /*
321  * call-seq:
322  * enum.find_all { |obj| block } -> array
323  * enum.select { |obj| block } -> array
324  * enum.find_all -> an_enumerator
325  * enum.select -> an_enumerator
326  *
327  * Returns an array containing all elements of +enum+
328  * for which the given +block+ returns a true value.
329  *
330  * If no block is given, an Enumerator is returned instead.
331  *
332  *
333  * (1..10).find_all { |i| i % 3 == 0 } #=> [3, 6, 9]
334  *
335  * [1,2,3,4,5].select { |num| num.even? } #=> [2, 4]
336  *
337  * See also Enumerable#reject.
338  */
339 
340 static VALUE
342 {
343  VALUE ary;
344 
346 
347  ary = rb_ary_new();
348  rb_block_call(obj, id_each, 0, 0, find_all_i, ary);
349 
350  return ary;
351 }
352 
353 static VALUE
355 {
357 
358  if (!RTEST(rb_yield(i))) {
359  rb_ary_push(ary, i);
360  }
361  return Qnil;
362 }
363 
364 /*
365  * call-seq:
366  * enum.reject { |obj| block } -> array
367  * enum.reject -> an_enumerator
368  *
369  * Returns an array for all elements of +enum+ for which the given
370  * +block+ returns false.
371  *
372  * If no block is given, an Enumerator is returned instead.
373  *
374  * (1..10).reject { |i| i % 3 == 0 } #=> [1, 2, 4, 5, 7, 8, 10]
375  *
376  * [1, 2, 3, 4, 5].reject { |num| num.even? } #=> [1, 3, 5]
377  *
378  * See also Enumerable#find_all.
379  */
380 
381 static VALUE
383 {
384  VALUE ary;
385 
387 
388  ary = rb_ary_new();
389  rb_block_call(obj, id_each, 0, 0, reject_i, ary);
390 
391  return ary;
392 }
393 
394 static VALUE
396 {
397  rb_ary_push(ary, enum_yield(argc, argv));
398 
399  return Qnil;
400 }
401 
402 static VALUE
404 {
406  rb_ary_push(ary, rb_enum_values_pack(argc, argv));
407 
408  return Qnil;
409 }
410 
411 /*
412  * call-seq:
413  * enum.collect { |obj| block } -> array
414  * enum.map { |obj| block } -> array
415  * enum.collect -> an_enumerator
416  * enum.map -> an_enumerator
417  *
418  * Returns a new array with the results of running <em>block</em> once
419  * for every element in <i>enum</i>.
420  *
421  * If no block is given, an enumerator is returned instead.
422  *
423  * (1..4).collect { |i| i*i } #=> [1, 4, 9, 16]
424  * (1..4).collect { "cat" } #=> ["cat", "cat", "cat", "cat"]
425  *
426  */
427 
428 static VALUE
430 {
431  VALUE ary;
432 
434 
435  ary = rb_ary_new();
436  rb_block_call(obj, id_each, 0, 0, collect_i, ary);
437 
438  return ary;
439 }
440 
441 static VALUE
443 {
444  VALUE tmp;
445 
446  i = enum_yield(argc, argv);
447  tmp = rb_check_array_type(i);
448 
449  if (NIL_P(tmp)) {
450  rb_ary_push(ary, i);
451  }
452  else {
453  rb_ary_concat(ary, tmp);
454  }
455  return Qnil;
456 }
457 
458 /*
459  * call-seq:
460  * enum.flat_map { |obj| block } -> array
461  * enum.collect_concat { |obj| block } -> array
462  * enum.flat_map -> an_enumerator
463  * enum.collect_concat -> an_enumerator
464  *
465  * Returns a new array with the concatenated results of running
466  * <em>block</em> once for every element in <i>enum</i>.
467  *
468  * If no block is given, an enumerator is returned instead.
469  *
470  * [1, 2, 3, 4].flat_map { |e| [e, -e] } #=> [1, -1, 2, -2, 3, -3, 4, -4]
471  * [[1, 2], [3, 4]].flat_map { |e| e + [100] } #=> [1, 2, 100, 3, 4, 100]
472  *
473  */
474 
475 static VALUE
477 {
478  VALUE ary;
479 
481 
482  ary = rb_ary_new();
483  rb_block_call(obj, id_each, 0, 0, flat_map_i, ary);
484 
485  return ary;
486 }
487 
488 /*
489  * call-seq:
490  * enum.to_a -> array
491  * enum.entries -> array
492  *
493  * Returns an array containing the items in <i>enum</i>.
494  *
495  * (1..7).to_a #=> [1, 2, 3, 4, 5, 6, 7]
496  * { 'a'=>1, 'b'=>2, 'c'=>3 }.to_a #=> [["a", 1], ["b", 2], ["c", 3]]
497  */
498 static VALUE
500 {
501  VALUE ary = rb_ary_new();
502 
503  rb_block_call(obj, id_each, argc, argv, collect_all, ary);
504  OBJ_INFECT(ary, obj);
505 
506  return ary;
507 }
508 
509 static VALUE
511 {
512  NODE *memo = RNODE(p);
513 
515 
516  if (memo->u2.argc == 0) {
517  memo->u2.argc = 1;
518  memo->u1.value = i;
519  }
520  else {
521  memo->u1.value = rb_yield_values(2, memo->u1.value, i);
522  }
523  return Qnil;
524 }
525 
526 static VALUE
528 {
529  NODE *memo = RNODE(p);
530 
532 
533  if (memo->u2.argc == 0) {
534  memo->u2.argc = 1;
535  memo->u1.value = i;
536  }
537  else {
538  memo->u1.value = rb_funcall(memo->u1.value, memo->u3.id, 1, i);
539  }
540  return Qnil;
541 }
542 
543 /*
544  * call-seq:
545  * enum.inject(initial, sym) -> obj
546  * enum.inject(sym) -> obj
547  * enum.inject(initial) { |memo, obj| block } -> obj
548  * enum.inject { |memo, obj| block } -> obj
549  * enum.reduce(initial, sym) -> obj
550  * enum.reduce(sym) -> obj
551  * enum.reduce(initial) { |memo, obj| block } -> obj
552  * enum.reduce { |memo, obj| block } -> obj
553  *
554  * Combines all elements of <i>enum</i> by applying a binary
555  * operation, specified by a block or a symbol that names a
556  * method or operator.
557  *
558  * If you specify a block, then for each element in <i>enum</i>
559  * the block is passed an accumulator value (<i>memo</i>) and the element.
560  * If you specify a symbol instead, then each element in the collection
561  * will be passed to the named method of <i>memo</i>.
562  * In either case, the result becomes the new value for <i>memo</i>.
563  * At the end of the iteration, the final value of <i>memo</i> is the
564  * return value for the method.
565  *
566  * If you do not explicitly specify an <i>initial</i> value for <i>memo</i>,
567  * then the first element of collection is used as the initial value
568  * of <i>memo</i>.
569  *
570  *
571  * # Sum some numbers
572  * (5..10).reduce(:+) #=> 45
573  * # Same using a block and inject
574  * (5..10).inject { |sum, n| sum + n } #=> 45
575  * # Multiply some numbers
576  * (5..10).reduce(1, :*) #=> 151200
577  * # Same using a block
578  * (5..10).inject(1) { |product, n| product * n } #=> 151200
579  * # find the longest word
580  * longest = %w{ cat sheep bear }.inject do |memo, word|
581  * memo.length > word.length ? memo : word
582  * end
583  * longest #=> "sheep"
584  *
585  */
586 static VALUE
588 {
589  NODE *memo;
590  VALUE init, op;
591  VALUE (*iter)(VALUE, VALUE, int, VALUE*) = inject_i;
592 
593  switch (rb_scan_args(argc, argv, "02", &init, &op)) {
594  case 0:
595  break;
596  case 1:
597  if (rb_block_given_p()) {
598  break;
599  }
600  op = (VALUE)rb_to_id(init);
601  argc = 0;
602  init = Qnil;
603  iter = inject_op_i;
604  break;
605  case 2:
606  if (rb_block_given_p()) {
607  rb_warning("given block not used");
608  }
609  op = (VALUE)rb_to_id(op);
610  iter = inject_op_i;
611  break;
612  }
613  memo = NEW_MEMO(init, argc, op);
614  rb_block_call(obj, id_each, 0, 0, iter, (VALUE)memo);
615  return memo->u1.value;
616 }
617 
618 static VALUE
620 {
621  NODE *memo = RNODE(arys);
622  VALUE ary;
624 
625  if (RTEST(rb_yield(i))) {
626  ary = memo->u1.value;
627  }
628  else {
629  ary = memo->u2.value;
630  }
631  rb_ary_push(ary, i);
632  return Qnil;
633 }
634 
635 /*
636  * call-seq:
637  * enum.partition { |obj| block } -> [ true_array, false_array ]
638  * enum.partition -> an_enumerator
639  *
640  * Returns two arrays, the first containing the elements of
641  * <i>enum</i> for which the block evaluates to true, the second
642  * containing the rest.
643  *
644  * If no block is given, an enumerator is returned instead.
645  *
646  * (1..6).partition { |v| v.even? } #=> [[2, 4, 6], [1, 3, 5]]
647  *
648  */
649 
650 static VALUE
652 {
653  NODE *memo;
654 
656 
657  memo = NEW_MEMO(rb_ary_new(), rb_ary_new(), 0);
658  rb_block_call(obj, id_each, 0, 0, partition_i, (VALUE)memo);
659 
660  return rb_assoc_new(memo->u1.value, memo->u2.value);
661 }
662 
663 static VALUE
665 {
666  VALUE group;
667  VALUE values;
668 
670 
671  group = rb_yield(i);
672  values = rb_hash_aref(hash, group);
673  if (!RB_TYPE_P(values, T_ARRAY)) {
674  values = rb_ary_new3(1, i);
675  rb_hash_aset(hash, group, values);
676  }
677  else {
678  rb_ary_push(values, i);
679  }
680  return Qnil;
681 }
682 
683 /*
684  * call-seq:
685  * enum.group_by { |obj| block } -> a_hash
686  * enum.group_by -> an_enumerator
687  *
688  * Groups the collection by result of the block. Returns a hash where the
689  * keys are the evaluated result from the block and the values are
690  * arrays of elements in the collection that correspond to the key.
691  *
692  * If no block is given an enumerator is returned.
693  *
694  * (1..6).group_by { |i| i%3 } #=> {0=>[3, 6], 1=>[1, 4], 2=>[2, 5]}
695  *
696  */
697 
698 static VALUE
700 {
701  VALUE hash;
702 
704 
705  hash = rb_hash_new();
706  rb_block_call(obj, id_each, 0, 0, group_by_i, hash);
707  OBJ_INFECT(hash, obj);
708 
709  return hash;
710 }
711 
712 static VALUE
713 first_i(VALUE i, VALUE params, int argc, VALUE *argv)
714 {
715  NODE *memo = RNODE(params);
717 
718  memo->u1.value = i;
719  rb_iter_break();
720 
721  UNREACHABLE;
722 }
723 
724 static VALUE enum_take(VALUE obj, VALUE n);
725 
726 /*
727  * call-seq:
728  * enum.first -> obj or nil
729  * enum.first(n) -> an_array
730  *
731  * Returns the first element, or the first +n+ elements, of the enumerable.
732  * If the enumerable is empty, the first form returns <code>nil</code>, and the
733  * second form returns an empty array.
734  *
735  * %w[foo bar baz].first #=> "foo"
736  * %w[foo bar baz].first(2) #=> ["foo", "bar"]
737  * %w[foo bar baz].first(10) #=> ["foo", "bar", "baz"]
738  * [].first #=> nil
739  *
740  */
741 
742 static VALUE
744 {
745  NODE *memo;
746  rb_check_arity(argc, 0, 1);
747  if (argc > 0) {
748  return enum_take(obj, argv[0]);
749  }
750  else {
751  memo = NEW_MEMO(Qnil, 0, 0);
752  rb_block_call(obj, id_each, 0, 0, first_i, (VALUE)memo);
753  return memo->u1.value;
754  }
755 }
756 
757 
758 /*
759  * call-seq:
760  * enum.sort -> array
761  * enum.sort { |a, b| block } -> array
762  *
763  * Returns an array containing the items in <i>enum</i> sorted,
764  * either according to their own <code><=></code> method, or by using
765  * the results of the supplied block. The block should return -1, 0, or
766  * +1 depending on the comparison between <i>a</i> and <i>b</i>. As of
767  * Ruby 1.8, the method <code>Enumerable#sort_by</code> implements a
768  * built-in Schwartzian Transform, useful when key computation or
769  * comparison is expensive.
770  *
771  * %w(rhea kea flea).sort #=> ["flea", "kea", "rhea"]
772  * (1..10).sort { |a, b| b <=> a } #=> [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
773  */
774 
775 static VALUE
777 {
778  return rb_ary_sort(enum_to_a(0, 0, obj));
779 }
780 
781 #define SORT_BY_BUFSIZE 16
782 struct sort_by_data {
785  long n;
786 };
787 
788 static VALUE
790 {
791  struct sort_by_data *data = (struct sort_by_data *)&RNODE(_data)->u1;
792  VALUE ary = data->ary;
793  VALUE v;
794 
796 
797  v = rb_yield(i);
798 
799  if (RBASIC(ary)->klass) {
800  rb_raise(rb_eRuntimeError, "sort_by reentered");
801  }
802  if (RARRAY_LEN(data->buf) != SORT_BY_BUFSIZE*2) {
803  rb_raise(rb_eRuntimeError, "sort_by reentered");
804  }
805 
806  RARRAY_PTR(data->buf)[data->n*2] = v;
807  RARRAY_PTR(data->buf)[data->n*2+1] = i;
808  data->n++;
809  if (data->n == SORT_BY_BUFSIZE) {
810  rb_ary_concat(ary, data->buf);
811  data->n = 0;
812  }
813  return Qnil;
814 }
815 
816 static int
817 sort_by_cmp(const void *ap, const void *bp, void *data)
818 {
819  VALUE a;
820  VALUE b;
821  VALUE ary = (VALUE)data;
822 
823  if (RBASIC(ary)->klass) {
824  rb_raise(rb_eRuntimeError, "sort_by reentered");
825  }
826 
827  a = *(VALUE *)ap;
828  b = *(VALUE *)bp;
829 
830  return rb_cmpint(rb_funcall(a, id_cmp, 1, b), a, b);
831 }
832 
833 /*
834  * call-seq:
835  * enum.sort_by { |obj| block } -> array
836  * enum.sort_by -> an_enumerator
837  *
838  * Sorts <i>enum</i> using a set of keys generated by mapping the
839  * values in <i>enum</i> through the given block.
840  *
841  * If no block is given, an enumerator is returned instead.
842  *
843  * %w{apple pear fig}.sort_by { |word| word.length}
844  * #=> ["fig", "pear", "apple"]
845  *
846  * The current implementation of <code>sort_by</code> generates an
847  * array of tuples containing the original collection element and the
848  * mapped value. This makes <code>sort_by</code> fairly expensive when
849  * the keysets are simple.
850  *
851  * require 'benchmark'
852  *
853  * a = (1..100000).map { rand(100000) }
854  *
855  * Benchmark.bm(10) do |b|
856  * b.report("Sort") { a.sort }
857  * b.report("Sort by") { a.sort_by { |a| a } }
858  * end
859  *
860  * <em>produces:</em>
861  *
862  * user system total real
863  * Sort 0.180000 0.000000 0.180000 ( 0.175469)
864  * Sort by 1.980000 0.040000 2.020000 ( 2.013586)
865  *
866  * However, consider the case where comparing the keys is a non-trivial
867  * operation. The following code sorts some files on modification time
868  * using the basic <code>sort</code> method.
869  *
870  * files = Dir["*"]
871  * sorted = files.sort { |a, b| File.new(a).mtime <=> File.new(b).mtime }
872  * sorted #=> ["mon", "tues", "wed", "thurs"]
873  *
874  * This sort is inefficient: it generates two new <code>File</code>
875  * objects during every comparison. A slightly better technique is to
876  * use the <code>Kernel#test</code> method to generate the modification
877  * times directly.
878  *
879  * files = Dir["*"]
880  * sorted = files.sort { |a, b|
881  * test(?M, a) <=> test(?M, b)
882  * }
883  * sorted #=> ["mon", "tues", "wed", "thurs"]
884  *
885  * This still generates many unnecessary <code>Time</code> objects. A
886  * more efficient technique is to cache the sort keys (modification
887  * times in this case) before the sort. Perl users often call this
888  * approach a Schwartzian Transform, after Randal Schwartz. We
889  * construct a temporary array, where each element is an array
890  * containing our sort key along with the filename. We sort this array,
891  * and then extract the filename from the result.
892  *
893  * sorted = Dir["*"].collect { |f|
894  * [test(?M, f), f]
895  * }.sort.collect { |f| f[1] }
896  * sorted #=> ["mon", "tues", "wed", "thurs"]
897  *
898  * This is exactly what <code>sort_by</code> does internally.
899  *
900  * sorted = Dir["*"].sort_by { |f| test(?M, f) }
901  * sorted #=> ["mon", "tues", "wed", "thurs"]
902  */
903 
904 static VALUE
906 {
907  VALUE ary, buf;
908  NODE *memo;
909  long i;
910  struct sort_by_data *data;
911 
913 
914  if (RB_TYPE_P(obj, T_ARRAY) && RARRAY_LEN(obj) <= LONG_MAX/2) {
915  ary = rb_ary_new2(RARRAY_LEN(obj)*2);
916  }
917  else {
918  ary = rb_ary_new();
919  }
920  RBASIC(ary)->klass = 0;
922  rb_ary_store(buf, SORT_BY_BUFSIZE*2-1, Qnil);
923  memo = NEW_MEMO(0, 0, 0);
924  OBJ_INFECT(memo, obj);
925  data = (struct sort_by_data *)&memo->u1;
926  data->ary = ary;
927  data->buf = buf;
928  data->n = 0;
929  rb_block_call(obj, id_each, 0, 0, sort_by_i, (VALUE)memo);
930  ary = data->ary;
931  buf = data->buf;
932  if (data->n) {
933  rb_ary_resize(buf, data->n*2);
934  rb_ary_concat(ary, buf);
935  }
936  if (RARRAY_LEN(ary) > 2) {
937  ruby_qsort(RARRAY_PTR(ary), RARRAY_LEN(ary)/2, 2*sizeof(VALUE),
938  sort_by_cmp, (void *)ary);
939  }
940  if (RBASIC(ary)->klass) {
941  rb_raise(rb_eRuntimeError, "sort_by reentered");
942  }
943  for (i=1; i<RARRAY_LEN(ary); i+=2) {
944  RARRAY_PTR(ary)[i/2] = RARRAY_PTR(ary)[i];
945  }
946  rb_ary_resize(ary, RARRAY_LEN(ary)/2);
947  RBASIC(ary)->klass = rb_cArray;
948  OBJ_INFECT(ary, memo);
949 
950  return ary;
951 }
952 
953 #define ENUMFUNC(name) rb_block_given_p() ? name##_iter_i : name##_i
954 
955 #define DEFINE_ENUMFUNCS(name) \
956 static VALUE enum_##name##_func(VALUE result, NODE *memo); \
957 \
958 static VALUE \
959 name##_i(VALUE i, VALUE memo, int argc, VALUE *argv) \
960 { \
961  return enum_##name##_func(rb_enum_values_pack(argc, argv), RNODE(memo)); \
962 } \
963 \
964 static VALUE \
965 name##_iter_i(VALUE i, VALUE memo, int argc, VALUE *argv) \
966 { \
967  return enum_##name##_func(enum_yield(argc, argv), RNODE(memo)); \
968 } \
969 \
970 static VALUE \
971 enum_##name##_func(VALUE result, NODE *memo)
972 
974 {
975  if (!RTEST(result)) {
976  memo->u1.value = Qfalse;
977  rb_iter_break();
978  }
979  return Qnil;
980 }
981 
982 /*
983  * call-seq:
984  * enum.all? [{ |obj| block } ] -> true or false
985  *
986  * Passes each element of the collection to the given block. The method
987  * returns <code>true</code> if the block never returns
988  * <code>false</code> or <code>nil</code>. If the block is not given,
989  * Ruby adds an implicit block of <code>{ |obj| obj }</code> which will
990  * cause #all? to return +true+ when none of the collection members are
991  * +false+ or +nil+.
992  *
993  * %w[ant bear cat].all? { |word| word.length >= 3 } #=> true
994  * %w[ant bear cat].all? { |word| word.length >= 4 } #=> false
995  * [nil, true, 99].all? #=> false
996  *
997  */
998 
999 static VALUE
1001 {
1002  NODE *memo = NEW_MEMO(Qtrue, 0, 0);
1003  rb_block_call(obj, id_each, 0, 0, ENUMFUNC(all), (VALUE)memo);
1004  return memo->u1.value;
1005 }
1006 
1008 {
1009  if (RTEST(result)) {
1010  memo->u1.value = Qtrue;
1011  rb_iter_break();
1012  }
1013  return Qnil;
1014 }
1015 
1016 /*
1017  * call-seq:
1018  * enum.any? [{ |obj| block }] -> true or false
1019  *
1020  * Passes each element of the collection to the given block. The method
1021  * returns <code>true</code> if the block ever returns a value other
1022  * than <code>false</code> or <code>nil</code>. If the block is not
1023  * given, Ruby adds an implicit block of <code>{ |obj| obj }</code> that
1024  * will cause #any? to return +true+ if at least one of the collection
1025  * members is not +false+ or +nil+.
1026  *
1027  * %w[ant bear cat].any? { |word| word.length >= 3 } #=> true
1028  * %w[ant bear cat].any? { |word| word.length >= 4 } #=> true
1029  * [nil, true, 99].any? #=> true
1030  *
1031  */
1032 
1033 static VALUE
1035 {
1036  NODE *memo = NEW_MEMO(Qfalse, 0, 0);
1037  rb_block_call(obj, id_each, 0, 0, ENUMFUNC(any), (VALUE)memo);
1038  return memo->u1.value;
1039 }
1040 
1042 {
1043  if (RTEST(result)) {
1044  if (memo->u1.value == Qundef) {
1045  memo->u1.value = Qtrue;
1046  }
1047  else if (memo->u1.value == Qtrue) {
1048  memo->u1.value = Qfalse;
1049  rb_iter_break();
1050  }
1051  }
1052  return Qnil;
1053 }
1054 
1055 /*
1056  * call-seq:
1057  * enum.one? [{ |obj| block }] -> true or false
1058  *
1059  * Passes each element of the collection to the given block. The method
1060  * returns <code>true</code> if the block returns <code>true</code>
1061  * exactly once. If the block is not given, <code>one?</code> will return
1062  * <code>true</code> only if exactly one of the collection members is
1063  * true.
1064  *
1065  * %w{ant bear cat}.one? { |word| word.length == 4 } #=> true
1066  * %w{ant bear cat}.one? { |word| word.length > 4 } #=> false
1067  * %w{ant bear cat}.one? { |word| word.length < 4 } #=> false
1068  * [ nil, true, 99 ].one? #=> false
1069  * [ nil, true, false ].one? #=> true
1070  *
1071  */
1072 
1073 static VALUE
1075 {
1076  NODE *memo = NEW_MEMO(Qundef, 0, 0);
1077  VALUE result;
1078 
1079  rb_block_call(obj, id_each, 0, 0, ENUMFUNC(one), (VALUE)memo);
1080  result = memo->u1.value;
1081  if (result == Qundef) return Qfalse;
1082  return result;
1083 }
1084 
1086 {
1087  if (RTEST(result)) {
1088  memo->u1.value = Qfalse;
1089  rb_iter_break();
1090  }
1091  return Qnil;
1092 }
1093 
1094 /*
1095  * call-seq:
1096  * enum.none? [{ |obj| block }] -> true or false
1097  *
1098  * Passes each element of the collection to the given block. The method
1099  * returns <code>true</code> if the block never returns <code>true</code>
1100  * for all elements. If the block is not given, <code>none?</code> will return
1101  * <code>true</code> only if none of the collection members is true.
1102  *
1103  * %w{ant bear cat}.none? { |word| word.length == 5 } #=> true
1104  * %w{ant bear cat}.none? { |word| word.length >= 4 } #=> false
1105  * [].none? #=> true
1106  * [nil].none? #=> true
1107  * [nil, false].none? #=> true
1108  */
1109 static VALUE
1111 {
1112  NODE *memo = NEW_MEMO(Qtrue, 0, 0);
1113  rb_block_call(obj, id_each, 0, 0, ENUMFUNC(none), (VALUE)memo);
1114  return memo->u1.value;
1115 }
1116 
1117 static VALUE
1119 {
1120  VALUE cmp;
1121  NODE *memo = RNODE(args);
1122 
1123  ENUM_WANT_SVALUE();
1124 
1125  if (memo->u1.value == Qundef) {
1126  memo->u1.value = i;
1127  }
1128  else {
1129  cmp = rb_funcall(i, id_cmp, 1, memo->u1.value);
1130  if (rb_cmpint(cmp, i, memo->u1.value) < 0) {
1131  memo->u1.value = i;
1132  }
1133  }
1134  return Qnil;
1135 }
1136 
1137 static VALUE
1139 {
1140  VALUE cmp;
1141  NODE *memo = RNODE(args);
1142 
1143  ENUM_WANT_SVALUE();
1144 
1145  if (memo->u1.value == Qundef) {
1146  memo->u1.value = i;
1147  }
1148  else {
1149  cmp = rb_yield_values(2, i, memo->u1.value);
1150  if (rb_cmpint(cmp, i, memo->u1.value) < 0) {
1151  memo->u1.value = i;
1152  }
1153  }
1154  return Qnil;
1155 }
1156 
1157 
1158 /*
1159  * call-seq:
1160  * enum.min -> obj
1161  * enum.min { |a, b| block } -> obj
1162  *
1163  * Returns the object in <i>enum</i> with the minimum value. The
1164  * first form assumes all objects implement <code>Comparable</code>;
1165  * the second uses the block to return <em>a <=> b</em>.
1166  *
1167  * a = %w(albatross dog horse)
1168  * a.min #=> "albatross"
1169  * a.min { |a, b| a.length <=> b.length } #=> "dog"
1170  */
1171 
1172 static VALUE
1174 {
1175  NODE *memo = NEW_MEMO(Qundef, 0, 0);
1176  VALUE result;
1177 
1178  if (rb_block_given_p()) {
1179  rb_block_call(obj, id_each, 0, 0, min_ii, (VALUE)memo);
1180  }
1181  else {
1182  rb_block_call(obj, id_each, 0, 0, min_i, (VALUE)memo);
1183  }
1184  result = memo->u1.value;
1185  if (result == Qundef) return Qnil;
1186  return result;
1187 }
1188 
1189 static VALUE
1191 {
1192  NODE *memo = RNODE(args);
1193  VALUE cmp;
1194 
1195  ENUM_WANT_SVALUE();
1196 
1197  if (memo->u1.value == Qundef) {
1198  memo->u1.value = i;
1199  }
1200  else {
1201  cmp = rb_funcall(i, id_cmp, 1, memo->u1.value);
1202  if (rb_cmpint(cmp, i, memo->u1.value) > 0) {
1203  memo->u1.value = i;
1204  }
1205  }
1206  return Qnil;
1207 }
1208 
1209 static VALUE
1211 {
1212  NODE *memo = RNODE(args);
1213  VALUE cmp;
1214 
1215  ENUM_WANT_SVALUE();
1216 
1217  if (memo->u1.value == Qundef) {
1218  memo->u1.value = i;
1219  }
1220  else {
1221  cmp = rb_yield_values(2, i, memo->u1.value);
1222  if (rb_cmpint(cmp, i, memo->u1.value) > 0) {
1223  memo->u1.value = i;
1224  }
1225  }
1226  return Qnil;
1227 }
1228 
1229 /*
1230  * call-seq:
1231  * enum.max -> obj
1232  * enum.max { |a, b| block } -> obj
1233  *
1234  * Returns the object in _enum_ with the maximum value. The
1235  * first form assumes all objects implement <code>Comparable</code>;
1236  * the second uses the block to return <em>a <=> b</em>.
1237  *
1238  * a = %w(albatross dog horse)
1239  * a.max #=> "horse"
1240  * a.max { |a, b| a.length <=> b.length } #=> "albatross"
1241  */
1242 
1243 static VALUE
1245 {
1246  NODE *memo = NEW_MEMO(Qundef, 0, 0);
1247  VALUE result;
1248 
1249  if (rb_block_given_p()) {
1250  rb_block_call(obj, id_each, 0, 0, max_ii, (VALUE)memo);
1251  }
1252  else {
1253  rb_block_call(obj, id_each, 0, 0, max_i, (VALUE)memo);
1254  }
1255  result = memo->u1.value;
1256  if (result == Qundef) return Qnil;
1257  return result;
1258 }
1259 
1260 struct minmax_t {
1264 };
1265 
1266 STATIC_ASSERT(minmax_t, sizeof(struct minmax_t) <= sizeof(NODE) - offsetof(NODE, u1));
1267 
1268 static void
1270 {
1271  int n;
1272 
1273  if (memo->min == Qundef) {
1274  memo->min = i;
1275  memo->max = j;
1276  }
1277  else {
1278  n = rb_cmpint(rb_funcall(i, id_cmp, 1, memo->min), i, memo->min);
1279  if (n < 0) {
1280  memo->min = i;
1281  }
1282  n = rb_cmpint(rb_funcall(j, id_cmp, 1, memo->max), j, memo->max);
1283  if (n > 0) {
1284  memo->max = j;
1285  }
1286  }
1287 }
1288 
1289 static VALUE
1291 {
1292  struct minmax_t *memo = (struct minmax_t *)&RNODE(_memo)->u1.value;
1293  int n;
1294  VALUE j;
1295 
1296  ENUM_WANT_SVALUE();
1297 
1298  if (memo->last == Qundef) {
1299  memo->last = i;
1300  return Qnil;
1301  }
1302  j = memo->last;
1303  memo->last = Qundef;
1304 
1305  n = rb_cmpint(rb_funcall(j, id_cmp, 1, i), j, i);
1306  if (n == 0)
1307  i = j;
1308  else if (n < 0) {
1309  VALUE tmp;
1310  tmp = i;
1311  i = j;
1312  j = tmp;
1313  }
1314 
1315  minmax_i_update(i, j, memo);
1316 
1317  return Qnil;
1318 }
1319 
1320 static void
1322 {
1323  int n;
1324 
1325  if (memo->min == Qundef) {
1326  memo->min = i;
1327  memo->max = j;
1328  }
1329  else {
1330  n = rb_cmpint(rb_yield_values(2, i, memo->min), i, memo->min);
1331  if (n < 0) {
1332  memo->min = i;
1333  }
1334  n = rb_cmpint(rb_yield_values(2, j, memo->max), j, memo->max);
1335  if (n > 0) {
1336  memo->max = j;
1337  }
1338  }
1339 }
1340 
1341 static VALUE
1343 {
1344  struct minmax_t *memo = (struct minmax_t *)&RNODE(_memo)->u1.value;
1345  int n;
1346  VALUE j;
1347 
1348  ENUM_WANT_SVALUE();
1349 
1350  if (memo->last == Qundef) {
1351  memo->last = i;
1352  return Qnil;
1353  }
1354  j = memo->last;
1355  memo->last = Qundef;
1356 
1357  n = rb_cmpint(rb_yield_values(2, j, i), j, i);
1358  if (n == 0)
1359  i = j;
1360  else if (n < 0) {
1361  VALUE tmp;
1362  tmp = i;
1363  i = j;
1364  j = tmp;
1365  }
1366 
1367  minmax_ii_update(i, j, memo);
1368 
1369  return Qnil;
1370 }
1371 
1372 /*
1373  * call-seq:
1374  * enum.minmax -> [min, max]
1375  * enum.minmax { |a, b| block } -> [min, max]
1376  *
1377  * Returns two elements array which contains the minimum and the
1378  * maximum value in the enumerable. The first form assumes all
1379  * objects implement <code>Comparable</code>; the second uses the
1380  * block to return <em>a <=> b</em>.
1381  *
1382  * a = %w(albatross dog horse)
1383  * a.minmax #=> ["albatross", "horse"]
1384  * a.minmax { |a, b| a.length <=> b.length } #=> ["dog", "albatross"]
1385  */
1386 
1387 static VALUE
1389 {
1390  NODE *memo = NEW_MEMO(Qundef, Qundef, Qundef);
1391  struct minmax_t *m = (struct minmax_t *)&memo->u1.value;
1392  VALUE ary = rb_ary_new3(2, Qnil, Qnil);
1393 
1394  m->min = Qundef;
1395  m->last = Qundef;
1396  if (rb_block_given_p()) {
1397  rb_block_call(obj, id_each, 0, 0, minmax_ii, (VALUE)memo);
1398  if (m->last != Qundef)
1399  minmax_ii_update(m->last, m->last, m);
1400  }
1401  else {
1402  rb_block_call(obj, id_each, 0, 0, minmax_i, (VALUE)memo);
1403  if (m->last != Qundef)
1404  minmax_i_update(m->last, m->last, m);
1405  }
1406  if (m->min != Qundef) {
1407  rb_ary_store(ary, 0, m->min);
1408  rb_ary_store(ary, 1, m->max);
1409  }
1410  return ary;
1411 }
1412 
1413 static VALUE
1415 {
1416  NODE *memo = RNODE(args);
1417  VALUE v;
1418 
1419  ENUM_WANT_SVALUE();
1420 
1421  v = rb_yield(i);
1422  if (memo->u1.value == Qundef) {
1423  memo->u1.value = v;
1424  memo->u2.value = i;
1425  }
1426  else if (rb_cmpint(rb_funcall(v, id_cmp, 1, memo->u1.value), v, memo->u1.value) < 0) {
1427  memo->u1.value = v;
1428  memo->u2.value = i;
1429  }
1430  return Qnil;
1431 }
1432 
1433 /*
1434  * call-seq:
1435  * enum.min_by { |obj| block } -> obj
1436  * enum.min_by -> an_enumerator
1437  *
1438  * Returns the object in <i>enum</i> that gives the minimum
1439  * value from the given block.
1440  *
1441  * If no block is given, an enumerator is returned instead.
1442  *
1443  * a = %w(albatross dog horse)
1444  * a.min_by { |x| x.length } #=> "dog"
1445  */
1446 
1447 static VALUE
1449 {
1450  NODE *memo;
1451 
1452  RETURN_SIZED_ENUMERATOR(obj, 0, 0, enum_size);
1453 
1454  memo = NEW_MEMO(Qundef, Qnil, 0);
1455  rb_block_call(obj, id_each, 0, 0, min_by_i, (VALUE)memo);
1456  return memo->u2.value;
1457 }
1458 
1459 static VALUE
1461 {
1462  NODE *memo = RNODE(args);
1463  VALUE v;
1464 
1465  ENUM_WANT_SVALUE();
1466 
1467  v = rb_yield(i);
1468  if (memo->u1.value == Qundef) {
1469  memo->u1.value = v;
1470  memo->u2.value = i;
1471  }
1472  else if (rb_cmpint(rb_funcall(v, id_cmp, 1, memo->u1.value), v, memo->u1.value) > 0) {
1473  memo->u1.value = v;
1474  memo->u2.value = i;
1475  }
1476  return Qnil;
1477 }
1478 
1479 /*
1480  * call-seq:
1481  * enum.max_by { |obj| block } -> obj
1482  * enum.max_by -> an_enumerator
1483  *
1484  * Returns the object in <i>enum</i> that gives the maximum
1485  * value from the given block.
1486  *
1487  * If no block is given, an enumerator is returned instead.
1488  *
1489  * a = %w(albatross dog horse)
1490  * a.max_by { |x| x.length } #=> "albatross"
1491  */
1492 
1493 static VALUE
1495 {
1496  NODE *memo;
1497 
1498  RETURN_SIZED_ENUMERATOR(obj, 0, 0, enum_size);
1499 
1500  memo = NEW_MEMO(Qundef, Qnil, 0);
1501  rb_block_call(obj, id_each, 0, 0, max_by_i, (VALUE)memo);
1502  return memo->u2.value;
1503 }
1504 
1505 struct minmax_by_t {
1512 };
1513 
1514 static void
1515 minmax_by_i_update(VALUE v1, VALUE v2, VALUE i1, VALUE i2, struct minmax_by_t *memo)
1516 {
1517  if (memo->min_bv == Qundef) {
1518  memo->min_bv = v1;
1519  memo->max_bv = v2;
1520  memo->min = i1;
1521  memo->max = i2;
1522  }
1523  else {
1524  if (rb_cmpint(rb_funcall(v1, id_cmp, 1, memo->min_bv), v1, memo->min_bv) < 0) {
1525  memo->min_bv = v1;
1526  memo->min = i1;
1527  }
1528  if (rb_cmpint(rb_funcall(v2, id_cmp, 1, memo->max_bv), v2, memo->max_bv) > 0) {
1529  memo->max_bv = v2;
1530  memo->max = i2;
1531  }
1532  }
1533 }
1534 
1535 static VALUE
1537 {
1538  struct minmax_by_t *memo = MEMO_FOR(struct minmax_by_t, _memo);
1539  VALUE vi, vj, j;
1540  int n;
1541 
1542  ENUM_WANT_SVALUE();
1543 
1544  vi = rb_yield(i);
1545 
1546  if (memo->last_bv == Qundef) {
1547  memo->last_bv = vi;
1548  memo->last = i;
1549  return Qnil;
1550  }
1551  vj = memo->last_bv;
1552  j = memo->last;
1553  memo->last_bv = Qundef;
1554 
1555  n = rb_cmpint(rb_funcall(vj, id_cmp, 1, vi), vj, vi);
1556  if (n == 0) {
1557  i = j;
1558  vi = vj;
1559  }
1560  else if (n < 0) {
1561  VALUE tmp;
1562  tmp = i;
1563  i = j;
1564  j = tmp;
1565  tmp = vi;
1566  vi = vj;
1567  vj = tmp;
1568  }
1569 
1570  minmax_by_i_update(vi, vj, i, j, memo);
1571 
1572  return Qnil;
1573 }
1574 
1575 /*
1576  * call-seq:
1577  * enum.minmax_by { |obj| block } -> [min, max]
1578  * enum.minmax_by -> an_enumerator
1579  *
1580  * Returns a two element array containing the objects in
1581  * <i>enum</i> that correspond to the minimum and maximum values respectively
1582  * from the given block.
1583  *
1584  * If no block is given, an enumerator is returned instead.
1585  *
1586  * a = %w(albatross dog horse)
1587  * a.minmax_by { |x| x.length } #=> ["dog", "albatross"]
1588  */
1589 
1590 static VALUE
1592 {
1593  VALUE memo;
1594  struct minmax_by_t *m = NEW_MEMO_FOR(struct minmax_by_t, memo);
1595 
1596  RETURN_SIZED_ENUMERATOR(obj, 0, 0, enum_size);
1597 
1598  m->min_bv = Qundef;
1599  m->max_bv = Qundef;
1600  m->min = Qnil;
1601  m->max = Qnil;
1602  m->last_bv = Qundef;
1603  m->last = Qundef;
1604  rb_block_call(obj, id_each, 0, 0, minmax_by_i, memo);
1605  if (m->last_bv != Qundef)
1606  minmax_by_i_update(m->last_bv, m->last_bv, m->last, m->last, m);
1607  m = MEMO_FOR(struct minmax_by_t, memo);
1608  return rb_assoc_new(m->min, m->max);
1609 }
1610 
1611 static VALUE
1613 {
1614  NODE *memo = RNODE(args);
1615 
1616  if (rb_equal(rb_enum_values_pack(argc, argv), memo->u1.value)) {
1617  memo->u2.value = Qtrue;
1618  rb_iter_break();
1619  }
1620  return Qnil;
1621 }
1622 
1623 /*
1624  * call-seq:
1625  * enum.include?(obj) -> true or false
1626  * enum.member?(obj) -> true or false
1627  *
1628  * Returns <code>true</code> if any member of <i>enum</i> equals
1629  * <i>obj</i>. Equality is tested using <code>==</code>.
1630  *
1631  * IO.constants.include? :SEEK_SET #=> true
1632  * IO.constants.include? :SEEK_NO_FURTHER #=> false
1633  *
1634  */
1635 
1636 static VALUE
1638 {
1639  NODE *memo = NEW_MEMO(val, Qfalse, 0);
1640 
1641  rb_block_call(obj, id_each, 0, 0, member_i, (VALUE)memo);
1642  return memo->u2.value;
1643 }
1644 
1645 static VALUE
1647 {
1648  long n = RNODE(memo)->u3.cnt++;
1649 
1650  return rb_yield_values(2, rb_enum_values_pack(argc, argv), INT2NUM(n));
1651 }
1652 
1653 /*
1654  * call-seq:
1655  * enum.each_with_index(*args) { |obj, i| block } -> enum
1656  * enum.each_with_index(*args) -> an_enumerator
1657  *
1658  * Calls <em>block</em> with two arguments, the item and its index,
1659  * for each item in <i>enum</i>. Given arguments are passed through
1660  * to #each().
1661  *
1662  * If no block is given, an enumerator is returned instead.
1663  *
1664  * hash = Hash.new
1665  * %w(cat dog wombat).each_with_index { |item, index|
1666  * hash[item] = index
1667  * }
1668  * hash #=> {"cat"=>0, "dog"=>1, "wombat"=>2}
1669  *
1670  */
1671 
1672 static VALUE
1674 {
1675  NODE *memo;
1676 
1677  RETURN_SIZED_ENUMERATOR(obj, argc, argv, enum_size);
1678 
1679  memo = NEW_MEMO(0, 0, 0);
1680  rb_block_call(obj, id_each, argc, argv, each_with_index_i, (VALUE)memo);
1681  return obj;
1682 }
1683 
1684 
1685 /*
1686  * call-seq:
1687  * enum.reverse_each(*args) { |item| block } -> enum
1688  * enum.reverse_each(*args) -> an_enumerator
1689  *
1690  * Builds a temporary array and traverses that array in reverse order.
1691  *
1692  * If no block is given, an enumerator is returned instead.
1693  *
1694  * (1..3).reverse_each { |v| p v }
1695  *
1696  * produces:
1697  *
1698  * 3
1699  * 2
1700  * 1
1701  */
1702 
1703 static VALUE
1705 {
1706  VALUE ary;
1707  long i;
1708 
1709  RETURN_SIZED_ENUMERATOR(obj, argc, argv, enum_size);
1710 
1711  ary = enum_to_a(argc, argv, obj);
1712 
1713  for (i = RARRAY_LEN(ary); --i >= 0; ) {
1714  rb_yield(RARRAY_PTR(ary)[i]);
1715  }
1716 
1717  return obj;
1718 }
1719 
1720 
1721 static VALUE
1723 {
1724  ENUM_WANT_SVALUE();
1725  rb_yield(i);
1726  return Qnil;
1727 }
1728 
1729 /*
1730  * call-seq:
1731  * enum.each_entry { |obj| block } -> enum
1732  * enum.each_entry -> an_enumerator
1733  *
1734  * Calls <i>block</i> once for each element in +self+, passing that
1735  * element as a parameter, converting multiple values from yield to an
1736  * array.
1737  *
1738  * If no block is given, an enumerator is returned instead.
1739  *
1740  * class Foo
1741  * include Enumerable
1742  * def each
1743  * yield 1
1744  * yield 1, 2
1745  * yield
1746  * end
1747  * end
1748  * Foo.new.each_entry{ |o| p o }
1749  *
1750  * produces:
1751  *
1752  * 1
1753  * [1, 2]
1754  * nil
1755  *
1756  */
1757 
1758 static VALUE
1760 {
1761  RETURN_SIZED_ENUMERATOR(obj, argc, argv, enum_size);
1762  rb_block_call(obj, id_each, argc, argv, each_val_i, 0);
1763  return obj;
1764 }
1765 
1766 static VALUE
1768 {
1769  NODE *memo = RNODE(m);
1770  VALUE ary = memo->u1.value;
1771  VALUE v = Qnil;
1772  long size = memo->u3.cnt;
1773  ENUM_WANT_SVALUE();
1774 
1775  rb_ary_push(ary, i);
1776 
1777  if (RARRAY_LEN(ary) == size) {
1778  v = rb_yield(ary);
1779  memo->u1.value = rb_ary_new2(size);
1780  }
1781 
1782  return v;
1783 }
1784 
1785 static VALUE
1787 {
1788  VALUE n, size;
1789  long slice_size = NUM2LONG(RARRAY_PTR(args)[0]);
1790  if (slice_size <= 0) rb_raise(rb_eArgError, "invalid slice size");
1791 
1792  size = enum_size(obj, 0);
1793  if (size == Qnil) return Qnil;
1794 
1795  n = rb_funcall(size, '+', 1, LONG2NUM(slice_size-1));
1796  return rb_funcall(n, id_div, 1, LONG2FIX(slice_size));
1797 }
1798 
1799 /*
1800  * call-seq:
1801  * enum.each_slice(n) { ... } -> nil
1802  * enum.each_slice(n) -> an_enumerator
1803  *
1804  * Iterates the given block for each slice of <n> elements. If no
1805  * block is given, returns an enumerator.
1806  *
1807  * (1..10).each_slice(3) { |a| p a }
1808  * # outputs below
1809  * [1, 2, 3]
1810  * [4, 5, 6]
1811  * [7, 8, 9]
1812  * [10]
1813  *
1814  */
1815 static VALUE
1817 {
1818  long size = NUM2LONG(n);
1819  VALUE ary;
1820  NODE *memo;
1821 
1822  if (size <= 0) rb_raise(rb_eArgError, "invalid slice size");
1824  ary = rb_ary_new2(size);
1825  memo = NEW_MEMO(ary, 0, size);
1826  rb_block_call(obj, id_each, 0, 0, each_slice_i, (VALUE)memo);
1827  ary = memo->u1.value;
1828  if (RARRAY_LEN(ary) > 0) rb_yield(ary);
1829 
1830  return Qnil;
1831 }
1832 
1833 static VALUE
1835 {
1836  NODE *memo = RNODE(args);
1837  VALUE ary = memo->u1.value;
1838  VALUE v = Qnil;
1839  long size = memo->u3.cnt;
1840  ENUM_WANT_SVALUE();
1841 
1842  if (RARRAY_LEN(ary) == size) {
1843  rb_ary_shift(ary);
1844  }
1845  rb_ary_push(ary, i);
1846  if (RARRAY_LEN(ary) == size) {
1847  v = rb_yield(rb_ary_dup(ary));
1848  }
1849  return v;
1850 }
1851 
1852 static VALUE
1854 {
1855  VALUE n, size;
1856  long cons_size = NUM2LONG(RARRAY_PTR(args)[0]);
1857  if (cons_size <= 0) rb_raise(rb_eArgError, "invalid size");
1858 
1859  size = enum_size(obj, 0);
1860  if (size == Qnil) return Qnil;
1861 
1862  n = rb_funcall(size, '+', 1, LONG2NUM(1 - cons_size));
1863  return (rb_cmpint(rb_funcall(n, id_cmp, 1, LONG2FIX(0)), n, LONG2FIX(0)) == -1) ? LONG2FIX(0) : n;
1864 }
1865 
1866 /*
1867  * call-seq:
1868  * enum.each_cons(n) { ... } -> nil
1869  * enum.each_cons(n) -> an_enumerator
1870  *
1871  * Iterates the given block for each array of consecutive <n>
1872  * elements. If no block is given, returns an enumerator.
1873  *
1874  * e.g.:
1875  * (1..10).each_cons(3) { |a| p a }
1876  * # outputs below
1877  * [1, 2, 3]
1878  * [2, 3, 4]
1879  * [3, 4, 5]
1880  * [4, 5, 6]
1881  * [5, 6, 7]
1882  * [6, 7, 8]
1883  * [7, 8, 9]
1884  * [8, 9, 10]
1885  *
1886  */
1887 static VALUE
1889 {
1890  long size = NUM2LONG(n);
1891  NODE *memo;
1892 
1893  if (size <= 0) rb_raise(rb_eArgError, "invalid size");
1895  memo = NEW_MEMO(rb_ary_new2(size), 0, size);
1896  rb_block_call(obj, id_each, 0, 0, each_cons_i, (VALUE)memo);
1897 
1898  return Qnil;
1899 }
1900 
1901 static VALUE
1903 {
1904  ENUM_WANT_SVALUE();
1905  return rb_yield_values(2, i, memo);
1906 }
1907 
1908 /*
1909  * call-seq:
1910  * enum.each_with_object(obj) { |(*args), memo_obj| ... } -> obj
1911  * enum.each_with_object(obj) -> an_enumerator
1912  *
1913  * Iterates the given block for each element with an arbitrary
1914  * object given, and returns the initially given object.
1915  *
1916  * If no block is given, returns an enumerator.
1917  *
1918  * evens = (1..10).each_with_object([]) { |i, a| a << i*2 }
1919  * #=> [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
1920  *
1921  */
1922 static VALUE
1924 {
1925  RETURN_SIZED_ENUMERATOR(obj, 1, &memo, enum_size);
1926 
1927  rb_block_call(obj, id_each, 0, 0, each_with_object_i, memo);
1928 
1929  return memo;
1930 }
1931 
1932 static VALUE
1934 {
1935  volatile VALUE result = memo->u1.value;
1936  volatile VALUE args = memo->u2.value;
1937  long n = memo->u3.cnt++;
1938  volatile VALUE tmp;
1939  int i;
1940 
1941  tmp = rb_ary_new2(RARRAY_LEN(args) + 1);
1942  rb_ary_store(tmp, 0, rb_enum_values_pack(argc, argv));
1943  for (i=0; i<RARRAY_LEN(args); i++) {
1944  VALUE e = RARRAY_PTR(args)[i];
1945 
1946  if (RARRAY_LEN(e) <= n) {
1947  rb_ary_push(tmp, Qnil);
1948  }
1949  else {
1950  rb_ary_push(tmp, RARRAY_PTR(e)[n]);
1951  }
1952  }
1953  if (NIL_P(result)) {
1954  rb_yield(tmp);
1955  }
1956  else {
1957  rb_ary_push(result, tmp);
1958  }
1959  return Qnil;
1960 }
1961 
1962 static VALUE
1964 {
1965  return v[0] = rb_funcall(v[1], id_next, 0, 0);
1966 }
1967 
1968 static VALUE
1970 {
1971  return v[0] = Qundef;
1972 }
1973 
1974 static VALUE
1976 {
1977  volatile VALUE result = memo->u1.value;
1978  volatile VALUE args = memo->u2.value;
1979  volatile VALUE tmp;
1980  int i;
1981 
1982  tmp = rb_ary_new2(RARRAY_LEN(args) + 1);
1983  rb_ary_store(tmp, 0, rb_enum_values_pack(argc, argv));
1984  for (i=0; i<RARRAY_LEN(args); i++) {
1985  if (NIL_P(RARRAY_PTR(args)[i])) {
1986  rb_ary_push(tmp, Qnil);
1987  }
1988  else {
1989  VALUE v[2];
1990 
1991  v[1] = RARRAY_PTR(args)[i];
1993  if (v[0] == Qundef) {
1994  RARRAY_PTR(args)[i] = Qnil;
1995  v[0] = Qnil;
1996  }
1997  rb_ary_push(tmp, v[0]);
1998  }
1999  }
2000  if (NIL_P(result)) {
2001  rb_yield(tmp);
2002  }
2003  else {
2004  rb_ary_push(result, tmp);
2005  }
2006  return Qnil;
2007 }
2008 
2009 /*
2010  * call-seq:
2011  * enum.zip(arg, ...) -> an_array_of_array
2012  * enum.zip(arg, ...) { |arr| block } -> nil
2013  *
2014  * Takes one element from <i>enum</i> and merges corresponding
2015  * elements from each <i>args</i>. This generates a sequence of
2016  * <em>n</em>-element arrays, where <em>n</em> is one more than the
2017  * count of arguments. The length of the resulting sequence will be
2018  * <code>enum#size</code>. If the size of any argument is less than
2019  * <code>enum#size</code>, <code>nil</code> values are supplied. If
2020  * a block is given, it is invoked for each output array, otherwise
2021  * an array of arrays is returned.
2022  *
2023  * a = [ 4, 5, 6 ]
2024  * b = [ 7, 8, 9 ]
2025  *
2026  * [1, 2, 3].zip(a, b) #=> [[1, 4, 7], [2, 5, 8], [3, 6, 9]]
2027  * [1, 2].zip(a, b) #=> [[1, 4, 7], [2, 5, 8]]
2028  * a.zip([1, 2], [8]) #=> [[4, 1, 8], [5, 2, nil], [6, nil, nil]]
2029  *
2030  */
2031 
2032 static VALUE
2034 {
2035  int i;
2036  ID conv;
2037  NODE *memo;
2038  VALUE result = Qnil;
2039  VALUE args = rb_ary_new4(argc, argv);
2040  int allary = TRUE;
2041 
2042  argv = RARRAY_PTR(args);
2043  for (i=0; i<argc; i++) {
2044  VALUE ary = rb_check_array_type(argv[i]);
2045  if (NIL_P(ary)) {
2046  allary = FALSE;
2047  break;
2048  }
2049  argv[i] = ary;
2050  }
2051  if (!allary) {
2052  CONST_ID(conv, "to_enum");
2053  for (i=0; i<argc; i++) {
2054  if (!rb_respond_to(argv[i], id_each)) {
2055  rb_raise(rb_eTypeError, "wrong argument type %s (must respond to :each)",
2056  rb_obj_classname(argv[i]));
2057  }
2058  argv[i] = rb_funcall(argv[i], conv, 1, ID2SYM(id_each));
2059  }
2060  }
2061  if (!rb_block_given_p()) {
2062  result = rb_ary_new();
2063  }
2064  /* use NODE_DOT2 as memo(v, v, -) */
2065  memo = rb_node_newnode(NODE_DOT2, result, args, 0);
2066  rb_block_call(obj, id_each, 0, 0, allary ? zip_ary : zip_i, (VALUE)memo);
2067 
2068  return result;
2069 }
2070 
2071 static VALUE
2073 {
2074  NODE *memo = RNODE(args);
2075  rb_ary_push(memo->u1.value, rb_enum_values_pack(argc, argv));
2076  if (--memo->u3.cnt == 0) rb_iter_break();
2077  return Qnil;
2078 }
2079 
2080 /*
2081  * call-seq:
2082  * enum.take(n) -> array
2083  *
2084  * Returns first n elements from <i>enum</i>.
2085  *
2086  * a = [1, 2, 3, 4, 5, 0]
2087  * a.take(3) #=> [1, 2, 3]
2088  *
2089  */
2090 
2091 static VALUE
2093 {
2094  NODE *memo;
2095  VALUE result;
2096  long len = NUM2LONG(n);
2097 
2098  if (len < 0) {
2099  rb_raise(rb_eArgError, "attempt to take negative size");
2100  }
2101 
2102  if (len == 0) return rb_ary_new2(0);
2103  result = rb_ary_new2(len);
2104  memo = NEW_MEMO(result, 0, len);
2105  rb_block_call(obj, id_each, 0, 0, take_i, (VALUE)memo);
2106  return result;
2107 }
2108 
2109 
2110 static VALUE
2112 {
2113  if (!RTEST(enum_yield(argc, argv))) rb_iter_break();
2114  rb_ary_push(ary, rb_enum_values_pack(argc, argv));
2115  return Qnil;
2116 }
2117 
2118 /*
2119  * call-seq:
2120  * enum.take_while { |arr| block } -> array
2121  * enum.take_while -> an_enumerator
2122  *
2123  * Passes elements to the block until the block returns +nil+ or +false+,
2124  * then stops iterating and returns an array of all prior elements.
2125  *
2126  * If no block is given, an enumerator is returned instead.
2127  *
2128  * a = [1, 2, 3, 4, 5, 0]
2129  * a.take_while { |i| i < 3 } #=> [1, 2]
2130  *
2131  */
2132 
2133 static VALUE
2135 {
2136  VALUE ary;
2137 
2138  RETURN_ENUMERATOR(obj, 0, 0);
2139  ary = rb_ary_new();
2140  rb_block_call(obj, id_each, 0, 0, take_while_i, ary);
2141  return ary;
2142 }
2143 
2144 static VALUE
2146 {
2147  NODE *memo = RNODE(args);
2148  if (memo->u3.cnt == 0) {
2149  rb_ary_push(memo->u1.value, rb_enum_values_pack(argc, argv));
2150  }
2151  else {
2152  memo->u3.cnt--;
2153  }
2154  return Qnil;
2155 }
2156 
2157 /*
2158  * call-seq:
2159  * enum.drop(n) -> array
2160  *
2161  * Drops first n elements from <i>enum</i>, and returns rest elements
2162  * in an array.
2163  *
2164  * a = [1, 2, 3, 4, 5, 0]
2165  * a.drop(3) #=> [4, 5, 0]
2166  *
2167  */
2168 
2169 static VALUE
2171 {
2172  VALUE result;
2173  NODE *memo;
2174  long len = NUM2LONG(n);
2175 
2176  if (len < 0) {
2177  rb_raise(rb_eArgError, "attempt to drop negative size");
2178  }
2179 
2180  result = rb_ary_new();
2181  memo = NEW_MEMO(result, 0, len);
2182  rb_block_call(obj, id_each, 0, 0, drop_i, (VALUE)memo);
2183  return result;
2184 }
2185 
2186 
2187 static VALUE
2189 {
2190  NODE *memo = RNODE(args);
2191  ENUM_WANT_SVALUE();
2192 
2193  if (!memo->u3.state && !RTEST(rb_yield(i))) {
2194  memo->u3.state = TRUE;
2195  }
2196  if (memo->u3.state) {
2197  rb_ary_push(memo->u1.value, i);
2198  }
2199  return Qnil;
2200 }
2201 
2202 /*
2203  * call-seq:
2204  * enum.drop_while { |arr| block } -> array
2205  * enum.drop_while -> an_enumerator
2206  *
2207  * Drops elements up to, but not including, the first element for
2208  * which the block returns +nil+ or +false+ and returns an array
2209  * containing the remaining elements.
2210  *
2211  * If no block is given, an enumerator is returned instead.
2212  *
2213  * a = [1, 2, 3, 4, 5, 0]
2214  * a.drop_while { |i| i < 3 } #=> [3, 4, 5, 0]
2215  *
2216  */
2217 
2218 static VALUE
2220 {
2221  VALUE result;
2222  NODE *memo;
2223 
2224  RETURN_ENUMERATOR(obj, 0, 0);
2225  result = rb_ary_new();
2226  memo = NEW_MEMO(result, 0, FALSE);
2227  rb_block_call(obj, id_each, 0, 0, drop_while_i, (VALUE)memo);
2228  return result;
2229 }
2230 
2231 static VALUE
2233 {
2234  ENUM_WANT_SVALUE();
2235 
2236  rb_ary_push(ary, i);
2237  rb_yield(i);
2238  return Qnil;
2239 }
2240 
2241 static VALUE
2243 {
2244  long mul;
2245  VALUE n = Qnil;
2246  VALUE size = enum_size(self, args);
2247 
2248  if (size == Qnil) return Qnil;
2249 
2250  if (args && (RARRAY_LEN(args) > 0)) {
2251  n = RARRAY_PTR(args)[0];
2252  }
2253  if (n == Qnil) return DBL2NUM(INFINITY);
2254  mul = NUM2LONG(n);
2255  if (mul <= 0) return INT2FIX(0);
2256  return rb_funcall(size, '*', 1, LONG2FIX(mul));
2257 }
2258 
2259 /*
2260  * call-seq:
2261  * enum.cycle(n=nil) { |obj| block } -> nil
2262  * enum.cycle(n=nil) -> an_enumerator
2263  *
2264  * Calls <i>block</i> for each element of <i>enum</i> repeatedly _n_
2265  * times or forever if none or +nil+ is given. If a non-positive
2266  * number is given or the collection is empty, does nothing. Returns
2267  * +nil+ if the loop has finished without getting interrupted.
2268  *
2269  * Enumerable#cycle saves elements in an internal array so changes
2270  * to <i>enum</i> after the first pass have no effect.
2271  *
2272  * If no block is given, an enumerator is returned instead.
2273  *
2274  * a = ["a", "b", "c"]
2275  * a.cycle { |x| puts x } # print, a, b, c, a, b, c,.. forever.
2276  * a.cycle(2) { |x| puts x } # print, a, b, c, a, b, c.
2277  *
2278  */
2279 
2280 static VALUE
2282 {
2283  VALUE ary;
2284  VALUE nv = Qnil;
2285  long n, i, len;
2286 
2287  rb_scan_args(argc, argv, "01", &nv);
2288 
2289  RETURN_SIZED_ENUMERATOR(obj, argc, argv, enum_cycle_size);
2290  if (NIL_P(nv)) {
2291  n = -1;
2292  }
2293  else {
2294  n = NUM2LONG(nv);
2295  if (n <= 0) return Qnil;
2296  }
2297  ary = rb_ary_new();
2298  RBASIC(ary)->klass = 0;
2299  rb_block_call(obj, id_each, 0, 0, cycle_i, ary);
2300  len = RARRAY_LEN(ary);
2301  if (len == 0) return Qnil;
2302  while (n < 0 || 0 < --n) {
2303  for (i=0; i<len; i++) {
2304  rb_yield(RARRAY_PTR(ary)[i]);
2305  }
2306  }
2307  return Qnil;
2308 }
2309 
2310 struct chunk_arg {
2316 };
2317 
2318 static VALUE
2320 {
2321  struct chunk_arg *argp = MEMO_FOR(struct chunk_arg, _argp);
2322  VALUE v;
2323  VALUE alone = ID2SYM(rb_intern("_alone"));
2324  VALUE separator = ID2SYM(rb_intern("_separator"));
2325 
2326  ENUM_WANT_SVALUE();
2327 
2328  if (NIL_P(argp->state))
2329  v = rb_funcall(argp->categorize, id_call, 1, i);
2330  else
2331  v = rb_funcall(argp->categorize, id_call, 2, i, argp->state);
2332 
2333  if (v == alone) {
2334  if (!NIL_P(argp->prev_value)) {
2335  rb_funcall(argp->yielder, id_lshift, 1, rb_assoc_new(argp->prev_value, argp->prev_elts));
2336  argp->prev_value = argp->prev_elts = Qnil;
2337  }
2338  rb_funcall(argp->yielder, id_lshift, 1, rb_assoc_new(v, rb_ary_new3(1, i)));
2339  }
2340  else if (NIL_P(v) || v == separator) {
2341  if (!NIL_P(argp->prev_value)) {
2342  rb_funcall(argp->yielder, id_lshift, 1, rb_assoc_new(argp->prev_value, argp->prev_elts));
2343  argp->prev_value = argp->prev_elts = Qnil;
2344  }
2345  }
2346  else if (SYMBOL_P(v) && rb_id2name(SYM2ID(v))[0] == '_') {
2347  rb_raise(rb_eRuntimeError, "symbol begins with an underscore is reserved");
2348  }
2349  else {
2350  if (NIL_P(argp->prev_value)) {
2351  argp->prev_value = v;
2352  argp->prev_elts = rb_ary_new3(1, i);
2353  }
2354  else {
2355  if (rb_equal(argp->prev_value, v)) {
2356  rb_ary_push(argp->prev_elts, i);
2357  }
2358  else {
2359  rb_funcall(argp->yielder, id_lshift, 1, rb_assoc_new(argp->prev_value, argp->prev_elts));
2360  argp->prev_value = v;
2361  argp->prev_elts = rb_ary_new3(1, i);
2362  }
2363  }
2364  }
2365  return Qnil;
2366 }
2367 
2368 static VALUE
2370 {
2371  VALUE enumerable;
2372  VALUE arg;
2373  struct chunk_arg *memo = NEW_MEMO_FOR(struct chunk_arg, arg);
2374 
2375  enumerable = rb_ivar_get(enumerator, rb_intern("chunk_enumerable"));
2376  memo->categorize = rb_ivar_get(enumerator, rb_intern("chunk_categorize"));
2377  memo->state = rb_ivar_get(enumerator, rb_intern("chunk_initial_state"));
2378  memo->prev_value = Qnil;
2379  memo->prev_elts = Qnil;
2380  memo->yielder = yielder;
2381 
2382  if (!NIL_P(memo->state))
2383  memo->state = rb_obj_dup(memo->state);
2384 
2385  rb_block_call(enumerable, id_each, 0, 0, chunk_ii, arg);
2386  memo = MEMO_FOR(struct chunk_arg, arg);
2387  if (!NIL_P(memo->prev_elts))
2388  rb_funcall(memo->yielder, id_lshift, 1, rb_assoc_new(memo->prev_value, memo->prev_elts));
2389  return Qnil;
2390 }
2391 
2392 /*
2393  * call-seq:
2394  * enum.chunk { |elt| ... } -> an_enumerator
2395  * enum.chunk(initial_state) { |elt, state| ... } -> an_enumerator
2396  *
2397  * Enumerates over the items, chunking them together based on the return
2398  * value of the block.
2399  *
2400  * Consecutive elements which return the same block value are chunked together.
2401  *
2402  * For example, consecutive even numbers and odd numbers can be
2403  * chunked as follows.
2404  *
2405  * [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5].chunk { |n|
2406  * n.even?
2407  * }.each { |even, ary|
2408  * p [even, ary]
2409  * }
2410  * #=> [false, [3, 1]]
2411  * # [true, [4]]
2412  * # [false, [1, 5, 9]]
2413  * # [true, [2, 6]]
2414  * # [false, [5, 3, 5]]
2415  *
2416  * This method is especially useful for sorted series of elements.
2417  * The following example counts words for each initial letter.
2418  *
2419  * open("/usr/share/dict/words", "r:iso-8859-1") { |f|
2420  * f.chunk { |line| line.ord }.each { |ch, lines| p [ch.chr, lines.length] }
2421  * }
2422  * #=> ["\n", 1]
2423  * # ["A", 1327]
2424  * # ["B", 1372]
2425  * # ["C", 1507]
2426  * # ["D", 791]
2427  * # ...
2428  *
2429  * The following key values have special meaning:
2430  * - +nil+ and +:_separator+ specifies that the elements should be dropped.
2431  * - +:_alone+ specifies that the element should be chunked by itself.
2432  *
2433  * Any other symbols that begin with an underscore will raise an error:
2434  *
2435  * items.chunk { |item| :_underscore }
2436  * #=> RuntimeError: symbol begins with an underscore is reserved
2437  *
2438  * +nil+ and +:_separator+ can be used to ignore some elements.
2439  *
2440  * For example, the sequence of hyphens in svn log can be eliminated as follows:
2441  *
2442  * sep = "-"*72 + "\n"
2443  * IO.popen("svn log README") { |f|
2444  * f.chunk { |line|
2445  * line != sep || nil
2446  * }.each { |_, lines|
2447  * pp lines
2448  * }
2449  * }
2450  * #=> ["r20018 | knu | 2008-10-29 13:20:42 +0900 (Wed, 29 Oct 2008) | 2 lines\n",
2451  * # "\n",
2452  * # "* README, README.ja: Update the portability section.\n",
2453  * # "\n"]
2454  * # ["r16725 | knu | 2008-05-31 23:34:23 +0900 (Sat, 31 May 2008) | 2 lines\n",
2455  * # "\n",
2456  * # "* README, README.ja: Add a note about default C flags.\n",
2457  * # "\n"]
2458  * # ...
2459  *
2460  * Paragraphs separated by empty lines can be parsed as follows:
2461  *
2462  * File.foreach("README").chunk { |line|
2463  * /\A\s*\z/ !~ line || nil
2464  * }.each { |_, lines|
2465  * pp lines
2466  * }
2467  *
2468  * +:_alone+ can be used to force items into their own chunk.
2469  * For example, you can put lines that contain a URL by themselves,
2470  * and chunk the rest of the lines together, like this:
2471  *
2472  * pattern = /http/
2473  * open(filename) { |f|
2474  * f.chunk { |line| line =~ pattern ? :_alone : true }.each { |key, lines|
2475  * pp lines
2476  * }
2477  * }
2478  *
2479  * If the block needs to maintain state over multiple elements,
2480  * an +initial_state+ argument can be used.
2481  * If a non-nil value is given,
2482  * a reference to it is passed as the 2nd argument of the block for the
2483  * +chunk+ method, so state-changes to it persist across block calls.
2484  *
2485  */
2486 static VALUE
2487 enum_chunk(int argc, VALUE *argv, VALUE enumerable)
2488 {
2489  VALUE initial_state;
2490  VALUE enumerator;
2491 
2492  if (!rb_block_given_p())
2493  rb_raise(rb_eArgError, "no block given");
2494  rb_scan_args(argc, argv, "01", &initial_state);
2495 
2496  enumerator = rb_obj_alloc(rb_cEnumerator);
2497  rb_ivar_set(enumerator, rb_intern("chunk_enumerable"), enumerable);
2498  rb_ivar_set(enumerator, rb_intern("chunk_categorize"), rb_block_proc());
2499  rb_ivar_set(enumerator, rb_intern("chunk_initial_state"), initial_state);
2500  rb_block_call(enumerator, idInitialize, 0, 0, chunk_i, enumerator);
2501  return enumerator;
2502 }
2503 
2504 
2511 };
2512 
2513 static VALUE
2515 {
2516  struct slicebefore_arg *argp = MEMO_FOR(struct slicebefore_arg, _argp);
2517  VALUE header_p;
2518 
2519  ENUM_WANT_SVALUE();
2520 
2521  if (!NIL_P(argp->sep_pat))
2522  header_p = rb_funcall(argp->sep_pat, id_eqq, 1, i);
2523  else if (NIL_P(argp->state))
2524  header_p = rb_funcall(argp->sep_pred, id_call, 1, i);
2525  else
2526  header_p = rb_funcall(argp->sep_pred, id_call, 2, i, argp->state);
2527  if (RTEST(header_p)) {
2528  if (!NIL_P(argp->prev_elts))
2529  rb_funcall(argp->yielder, id_lshift, 1, argp->prev_elts);
2530  argp->prev_elts = rb_ary_new3(1, i);
2531  }
2532  else {
2533  if (NIL_P(argp->prev_elts))
2534  argp->prev_elts = rb_ary_new3(1, i);
2535  else
2536  rb_ary_push(argp->prev_elts, i);
2537  }
2538 
2539  return Qnil;
2540 }
2541 
2542 static VALUE
2544 {
2545  VALUE enumerable;
2546  VALUE arg;
2547  struct slicebefore_arg *memo = NEW_MEMO_FOR(struct slicebefore_arg, arg);
2548 
2549  enumerable = rb_ivar_get(enumerator, rb_intern("slicebefore_enumerable"));
2550  memo->sep_pred = rb_attr_get(enumerator, rb_intern("slicebefore_sep_pred"));
2551  memo->sep_pat = NIL_P(memo->sep_pred) ? rb_ivar_get(enumerator, rb_intern("slicebefore_sep_pat")) : Qnil;
2552  memo->state = rb_attr_get(enumerator, rb_intern("slicebefore_initial_state"));
2553  memo->prev_elts = Qnil;
2554  memo->yielder = yielder;
2555 
2556  if (!NIL_P(memo->state))
2557  memo->state = rb_obj_dup(memo->state);
2558 
2559  rb_block_call(enumerable, id_each, 0, 0, slicebefore_ii, arg);
2560  memo = MEMO_FOR(struct slicebefore_arg, arg);
2561  if (!NIL_P(memo->prev_elts))
2562  rb_funcall(memo->yielder, id_lshift, 1, memo->prev_elts);
2563  return Qnil;
2564 }
2565 
2566 /*
2567  * call-seq:
2568  * enum.slice_before(pattern) -> an_enumerator
2569  * enum.slice_before { |elt| bool } -> an_enumerator
2570  * enum.slice_before(initial_state) { |elt, state| bool } -> an_enumerator
2571  *
2572  * Creates an enumerator for each chunked elements.
2573  * The beginnings of chunks are defined by _pattern_ and the block.
2574 
2575  * If <code>_pattern_ === _elt_</code> returns <code>true</code> or the block
2576  * returns <code>true</code> for the element, the element is beginning of a
2577  * chunk.
2578 
2579  * The <code>===</code> and _block_ is called from the first element to the last
2580  * element of _enum_. The result for the first element is ignored.
2581 
2582  * The result enumerator yields the chunked elements as an array.
2583  * So +each+ method can be called as follows:
2584  *
2585  * enum.slice_before(pattern).each { |ary| ... }
2586  * enum.slice_before { |elt| bool }.each { |ary| ... }
2587  * enum.slice_before(initial_state) { |elt, state| bool }.each { |ary| ... }
2588  *
2589  * Other methods of the Enumerator class and Enumerable module,
2590  * such as map, etc., are also usable.
2591  *
2592  * For example, iteration over ChangeLog entries can be implemented as
2593  * follows:
2594  *
2595  * # iterate over ChangeLog entries.
2596  * open("ChangeLog") { |f|
2597  * f.slice_before(/\A\S/).each { |e| pp e }
2598  * }
2599  *
2600  * # same as above. block is used instead of pattern argument.
2601  * open("ChangeLog") { |f|
2602  * f.slice_before { |line| /\A\S/ === line }.each { |e| pp e }
2603  * }
2604  *
2605  *
2606  * "svn proplist -R" produces multiline output for each file.
2607  * They can be chunked as follows:
2608  *
2609  * IO.popen([{"LC_ALL"=>"C"}, "svn", "proplist", "-R"]) { |f|
2610  * f.lines.slice_before(/\AProp/).each { |lines| p lines }
2611  * }
2612  * #=> ["Properties on '.':\n", " svn:ignore\n", " svk:merge\n"]
2613  * # ["Properties on 'goruby.c':\n", " svn:eol-style\n"]
2614  * # ["Properties on 'complex.c':\n", " svn:mime-type\n", " svn:eol-style\n"]
2615  * # ["Properties on 'regparse.c':\n", " svn:eol-style\n"]
2616  * # ...
2617  *
2618  * If the block needs to maintain state over multiple elements,
2619  * local variables can be used.
2620  * For example, three or more consecutive increasing numbers can be squashed
2621  * as follows:
2622  *
2623  * a = [0, 2, 3, 4, 6, 7, 9]
2624  * prev = a[0]
2625  * p a.slice_before { |e|
2626  * prev, prev2 = e, prev
2627  * prev2 + 1 != e
2628  * }.map { |es|
2629  * es.length <= 2 ? es.join(",") : "#{es.first}-#{es.last}"
2630  * }.join(",")
2631  * #=> "0,2-4,6,7,9"
2632  *
2633  * However local variables are not appropriate to maintain state
2634  * if the result enumerator is used twice or more.
2635  * In such a case, the last state of the 1st +each+ is used in the 2nd +each+.
2636  * The _initial_state_ argument can be used to avoid this problem.
2637  * If non-nil value is given as _initial_state_,
2638  * it is duplicated for each +each+ method invocation of the enumerator.
2639  * The duplicated object is passed to 2nd argument of the block for
2640  * +slice_before+ method.
2641  *
2642  * # Word wrapping. This assumes all characters have same width.
2643  * def wordwrap(words, maxwidth)
2644  * # if cols is a local variable, 2nd "each" may start with non-zero cols.
2645  * words.slice_before(cols: 0) { |w, h|
2646  * h[:cols] += 1 if h[:cols] != 0
2647  * h[:cols] += w.length
2648  * if maxwidth < h[:cols]
2649  * h[:cols] = w.length
2650  * true
2651  * else
2652  * false
2653  * end
2654  * }
2655  * end
2656  * text = (1..20).to_a.join(" ")
2657  * enum = wordwrap(text.split(/\s+/), 10)
2658  * puts "-"*10
2659  * enum.each { |ws| puts ws.join(" ") }
2660  * puts "-"*10
2661  * #=> ----------
2662  * # 1 2 3 4 5
2663  * # 6 7 8 9 10
2664  * # 11 12 13
2665  * # 14 15 16
2666  * # 17 18 19
2667  * # 20
2668  * # ----------
2669  *
2670  * mbox contains series of mails which start with Unix From line.
2671  * So each mail can be extracted by slice before Unix From line.
2672  *
2673  * # parse mbox
2674  * open("mbox") { |f|
2675  * f.slice_before { |line|
2676  * line.start_with? "From "
2677  * }.each { |mail|
2678  * unix_from = mail.shift
2679  * i = mail.index("\n")
2680  * header = mail[0...i]
2681  * body = mail[(i+1)..-1]
2682  * body.pop if body.last == "\n"
2683  * fields = header.slice_before { |line| !" \t".include?(line[0]) }.to_a
2684  * p unix_from
2685  * pp fields
2686  * pp body
2687  * }
2688  * }
2689  *
2690  * # split mails in mbox (slice before Unix From line after an empty line)
2691  * open("mbox") { |f|
2692  * f.slice_before(emp: true) { |line, h|
2693  * prevemp = h[:emp]
2694  * h[:emp] = line == "\n"
2695  * prevemp && line.start_with?("From ")
2696  * }.each { |mail|
2697  * mail.pop if mail.last == "\n"
2698  * pp mail
2699  * }
2700  * }
2701  *
2702  */
2703 static VALUE
2705 {
2706  VALUE enumerator;
2707 
2708  if (rb_block_given_p()) {
2709  VALUE initial_state;
2710  rb_scan_args(argc, argv, "01", &initial_state);
2711  enumerator = rb_obj_alloc(rb_cEnumerator);
2712  rb_ivar_set(enumerator, rb_intern("slicebefore_sep_pred"), rb_block_proc());
2713  rb_ivar_set(enumerator, rb_intern("slicebefore_initial_state"), initial_state);
2714  }
2715  else {
2716  VALUE sep_pat;
2717  rb_scan_args(argc, argv, "1", &sep_pat);
2718  enumerator = rb_obj_alloc(rb_cEnumerator);
2719  rb_ivar_set(enumerator, rb_intern("slicebefore_sep_pat"), sep_pat);
2720  }
2721  rb_ivar_set(enumerator, rb_intern("slicebefore_enumerable"), enumerable);
2722  rb_block_call(enumerator, idInitialize, 0, 0, slicebefore_i, enumerator);
2723  return enumerator;
2724 }
2725 
2726 /*
2727  * The <code>Enumerable</code> mixin provides collection classes with
2728  * several traversal and searching methods, and with the ability to
2729  * sort. The class must provide a method <code>each</code>, which
2730  * yields successive members of the collection. If
2731  * <code>Enumerable#max</code>, <code>#min</code>, or
2732  * <code>#sort</code> is used, the objects in the collection must also
2733  * implement a meaningful <code><=></code> operator, as these methods
2734  * rely on an ordering between members of the collection.
2735  */
2736 
2737 void
2739 {
2740 #undef rb_intern
2741 #define rb_intern(str) rb_intern_const(str)
2742 
2743  rb_mEnumerable = rb_define_module("Enumerable");
2744 
2746  rb_define_method(rb_mEnumerable, "entries", enum_to_a, -1);
2747 
2753  rb_define_method(rb_mEnumerable, "detect", enum_find, -1);
2754  rb_define_method(rb_mEnumerable, "find_index", enum_find_index, -1);
2761  rb_define_method(rb_mEnumerable, "collect_concat", enum_flat_map, 0);
2778  rb_define_method(rb_mEnumerable, "include?", enum_member, 1);
2779  rb_define_method(rb_mEnumerable, "each_with_index", enum_each_with_index, -1);
2780  rb_define_method(rb_mEnumerable, "reverse_each", enum_reverse_each, -1);
2781  rb_define_method(rb_mEnumerable, "each_entry", enum_each_entry, -1);
2782  rb_define_method(rb_mEnumerable, "each_slice", enum_each_slice, 1);
2784  rb_define_method(rb_mEnumerable, "each_with_object", enum_each_with_object, 1);
2787  rb_define_method(rb_mEnumerable, "take_while", enum_take_while, 0);
2789  rb_define_method(rb_mEnumerable, "drop_while", enum_drop_while, 0);
2792  rb_define_method(rb_mEnumerable, "slice_before", enum_slice_before, -1);
2793 
2794  id_next = rb_intern("next");
2795  id_call = rb_intern("call");
2796  id_size = rb_intern("size");
2797  id_div = rb_intern("div");
2798 }
#define id_lshift
Definition: enum.c:30
static VALUE count_i(VALUE i, VALUE memop, int argc, VALUE *argv)
Definition: enum.c:100
static VALUE enum_any(VALUE obj)
Definition: enum.c:1034
VALUE rb_ary_new4(long n, const VALUE *elts)
Definition: array.c:451
#define RARRAY_LEN(a)
Definition: ruby.h:899
#define rb_intern(str)
static VALUE minmax_ii(VALUE i, VALUE _memo, int argc, VALUE *argv)
Definition: enum.c:1342
static VALUE enum_all(VALUE obj)
Definition: enum.c:1000
#define FALSE
Definition: nkf.h:174
#define NEW_MEMO_FOR(type, value)
Definition: node.h:464
static VALUE grep_i(VALUE i, VALUE args, int argc, VALUE *argv)
Definition: enum.c:47
#define id_each
Definition: enum.c:27
#define INT2NUM(x)
Definition: ruby.h:1178
int i
Definition: win32ole.c:784
static VALUE each_cons_i(VALUE i, VALUE args, int argc, VALUE *argv)
Definition: enum.c:1834
static VALUE chunk_ii(VALUE i, VALUE _argp, int argc, VALUE *argv)
Definition: enum.c:2319
VALUE state
Definition: enum.c:2312
static VALUE enum_each_with_index(int argc, VALUE *argv, VALUE obj)
Definition: enum.c:1673
static VALUE min_by_i(VALUE i, VALUE args, int argc, VALUE *argv)
Definition: enum.c:1414
static VALUE min_ii(VALUE i, VALUE args, int argc, VALUE *argv)
Definition: enum.c:1138
VALUE rb_yield_values(int n,...)
Definition: vm_eval.c:945
static VALUE group_by_i(VALUE i, VALUE hash, int argc, VALUE *argv)
Definition: enum.c:664
static int sort_by_cmp(const void *ap, const void *bp, void *data)
Definition: enum.c:817
VALUE rb_ary_sort(VALUE ary)
Definition: array.c:2373
#define MEMO_FOR(type, value)
Definition: node.h:463
static VALUE take_i(VALUE i, VALUE args, int argc, VALUE *argv)
Definition: enum.c:2072
static VALUE flat_map_i(VALUE i, VALUE ary, int argc, VALUE *argv)
Definition: enum.c:442
static VALUE find_i(VALUE i, VALUE memop, int argc, VALUE *argv)
Definition: enum.c:179
#define Qtrue
Definition: ruby.h:434
VALUE rb_ary_shift(VALUE ary)
Definition: array.c:929
static VALUE enum_each_slice(VALUE obj, VALUE n)
Definition: enum.c:1816
static VALUE enum_each_slice_size(VALUE obj, VALUE args)
Definition: enum.c:1786
VALUE rb_eTypeError
Definition: error.c:511
static VALUE enum_cycle_size(VALUE self, VALUE args)
Definition: enum.c:2242
static VALUE inject_op_i(VALUE i, VALUE p, int argc, VALUE *argv)
Definition: enum.c:527
VALUE state
Definition: enum.c:2508
#define UNREACHABLE
Definition: ruby.h:40
VALUE sep_pred
Definition: enum.c:2506
static VALUE drop_while_i(VALUE i, VALUE args, int argc, VALUE *argv)
Definition: enum.c:2188
VALUE rb_ary_push(VALUE ary, VALUE item)
Definition: array.c:822
SSL_METHOD *(* func)(void)
Definition: ossl_ssl.c:108
union RNode::@93 u1
#define SYM2ID(x)
Definition: ruby.h:364
static VALUE enum_each_cons(VALUE obj, VALUE n)
Definition: enum.c:1888
VALUE yielder
Definition: enum.c:2510
VALUE rb_ary_tmp_new(long capa)
Definition: array.c:465
static VALUE zip_i(VALUE val, NODE *memo, int argc, VALUE *argv)
Definition: enum.c:1975
static VALUE chunk_i(VALUE yielder, VALUE enumerator, int argc, VALUE *argv)
Definition: enum.c:2369
static VALUE enum_sort_by(VALUE obj)
Definition: enum.c:905
VALUE rb_funcall(VALUE, ID, int,...)
Calls a method.
Definition: vm_eval.c:774
static VALUE enum_member(VALUE obj, VALUE val)
Definition: enum.c:1637
VALUE rb_cEnumerator
Definition: enumerator.c:105
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:1780
ID id
Definition: node.h:244
VALUE rb_ivar_get(VALUE, ID)
Definition: variable.c:1116
#define DEFINE_ENUMFUNCS(name)
Definition: enum.c:955
static VALUE enum_slice_before(int argc, VALUE *argv, VALUE enumerable)
Definition: enum.c:2704
static VALUE take_while_i(VALUE i, VALUE ary, int argc, VALUE *argv)
Definition: enum.c:2111
VALUE rb_ary_new3(long n,...)
Definition: array.c:432
static VALUE partition_i(VALUE i, VALUE arys, int argc, VALUE *argv)
Definition: enum.c:619
#define T_ARRAY
Definition: ruby.h:492
VALUE max
Definition: enum.c:1509
VALUE max
Definition: enum.c:1262
VALUE rb_block_call(VALUE, ID, int, VALUE *, VALUE(*)(ANYARGS), VALUE)
Definition: vm_eval.c:1131
long argc
Definition: node.h:252
VALUE yielder
Definition: enum.c:2315
VALUE last
Definition: enum.c:1263
int rb_cmpint(VALUE val, VALUE a, VALUE b)
Definition: bignum.c:97
const char * rb_obj_classname(VALUE)
Definition: variable.c:396
static VALUE slicebefore_i(VALUE yielder, VALUE enumerator, int argc, VALUE *argv)
Definition: enum.c:2543
Definition: node.h:239
void Init_Enumerable(void)
Definition: enum.c:2738
Win32OLEIDispatch * p
Definition: win32ole.c:786
static VALUE each_with_index_i(VALUE i, VALUE memo, int argc, VALUE *argv)
Definition: enum.c:1646
#define ENUM_WANT_SVALUE()
Definition: enum.c:40
static VALUE collect_i(VALUE i, VALUE ary, int argc, VALUE *argv)
Definition: enum.c:395
int args
Definition: win32ole.c:785
VALUE rb_obj_dup(VALUE)
Definition: object.c:338
VALUE prev_value
Definition: enum.c:2313
#define RB_TYPE_P(obj, type)
Definition: ruby.h:1537
static VALUE enum_max(VALUE obj)
Definition: enum.c:1244
static VALUE enum_max_by(VALUE obj)
Definition: enum.c:1494
void rb_iter_break(void)
Definition: vm.c:960
long n
Definition: enum.c:785
static ID id_size
Definition: enum.c:25
static VALUE max_ii(VALUE i, VALUE args, int argc, VALUE *argv)
Definition: enum.c:1210
static VALUE enum_take(VALUE obj, VALUE n)
Definition: enum.c:2092
static VALUE enum_chunk(int argc, VALUE *argv, VALUE enumerable)
Definition: enum.c:2487
static VALUE each_val_i(VALUE i, VALUE p, int argc, VALUE *argv)
Definition: enum.c:1722
int rb_block_given_p(void)
Definition: eval.c:672
static VALUE max_i(VALUE i, VALUE args, int argc, VALUE *argv)
Definition: enum.c:1190
static VALUE find_all_i(VALUE i, VALUE ary, int argc, VALUE *argv)
Definition: enum.c:302
#define val
VALUE rb_eRuntimeError
Definition: error.c:510
static VALUE enum_sort(VALUE obj)
Definition: enum.c:776
static VALUE count_all_i(VALUE i, VALUE memop, int argc, VALUE *argv)
Definition: enum.c:124
static VALUE enum_each_entry(int argc, VALUE *argv, VALUE obj)
Definition: enum.c:1759
VALUE rb_ary_new(void)
Definition: array.c:424
static VALUE enum_inject(int argc, VALUE *argv, VALUE obj)
Definition: enum.c:587
#define UINT2NUM(x)
Definition: ruby.h:1188
static VALUE enum_grep(VALUE obj, VALUE pat)
Definition: enum.c:89
#define NIL_P(v)
Definition: ruby.h:446
static VALUE enum_find_all(VALUE obj)
Definition: enum.c:341
#define SORT_BY_BUFSIZE
Definition: enum.c:781
void rb_ary_store(VALUE ary, long idx, VALUE val)
Definition: array.c:719
VALUE value
Definition: node.h:245
#define offsetof(p_type, field)
Definition: addrinfo.h:186
static VALUE count_iter_i(VALUE i, VALUE memop, int argc, VALUE *argv)
Definition: enum.c:113
static void minmax_i_update(VALUE i, VALUE j, struct minmax_t *memo)
Definition: enum.c:1269
static double one(void)
Definition: isinf.c:52
int argc
Definition: ruby.c:130
#define Qfalse
Definition: ruby.h:433
static VALUE enum_first(int argc, VALUE *argv, VALUE obj)
Definition: enum.c:743
#define LONG_MAX
Definition: ruby.h:201
#define STATIC_ASSERT(name, expr)
Definition: enum.c:18
VALUE rb_obj_alloc(VALUE)
Definition: object.c:1721
#define RNODE(obj)
Definition: node.h:266
static void minmax_by_i_update(VALUE v1, VALUE v2, VALUE i1, VALUE i2, struct minmax_by_t *memo)
Definition: enum.c:1515
long cnt
Definition: node.h:261
static VALUE min_i(VALUE i, VALUE args, int argc, VALUE *argv)
Definition: enum.c:1118
static VALUE enum_cycle(int argc, VALUE *argv, VALUE obj)
Definition: enum.c:2281
union RNode::@94 u2
VALUE rb_yield(VALUE)
Definition: vm_eval.c:934
#define TRUE
Definition: nkf.h:175
static VALUE each_with_object_i(VALUE i, VALUE memo, int argc, VALUE *argv)
Definition: enum.c:1902
VALUE rb_check_funcall(VALUE, ID, int, VALUE *)
Definition: vm_eval.c:408
VALUE rb_mEnumerable
Definition: enum.c:20
static VALUE first_i(VALUE i, VALUE params, int argc, VALUE *argv)
Definition: enum.c:713
VALUE categorize
Definition: enum.c:2311
#define rb_node_newnode(type, a1, a2, a3)
Definition: ripper.c:419
static VALUE drop_i(VALUE i, VALUE args, int argc, VALUE *argv)
Definition: enum.c:2145
union RNode::@95 u3
static VALUE find_index_iter_i(VALUE i, VALUE memop, int argc, VALUE *argv)
Definition: enum.c:246
VALUE rb_hash_new(void)
Definition: hash.c:234
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
Definition: class.c:1570
static VALUE cycle_i(VALUE i, VALUE ary, int argc, VALUE *argv)
Definition: enum.c:2232
VALUE rb_ivar_set(VALUE, ID, VALUE)
Definition: variable.c:1128
VALUE sep_pat
Definition: enum.c:2507
unsigned char buf[MIME_BUF_SIZE]
Definition: nkf.c:4308
VALUE rb_assoc_new(VALUE car, VALUE cdr)
Definition: array.c:545
static void minmax_ii_update(VALUE i, VALUE j, struct minmax_t *memo)
Definition: enum.c:1321
unsigned long ID
Definition: ruby.h:105
VALUE min_bv
Definition: enum.c:1506
#define Qnil
Definition: ruby.h:435
VALUE rb_eStopIteration
Definition: enumerator.c:111
static VALUE max_by_i(VALUE i, VALUE args, int argc, VALUE *argv)
Definition: enum.c:1460
unsigned long VALUE
Definition: ruby.h:104
static VALUE enum_collect(VALUE obj)
Definition: enum.c:429
#define id_cmp
Definition: enum.c:29
void ruby_qsort(void *, const size_t, const size_t, int(*)(const void *, const void *, void *), void *)
static VALUE result
Definition: nkf.c:40
#define RETURN_SIZED_ENUMERATOR(obj, argc, argv, size_fn)
Definition: intern.h:215
#define RBASIC(obj)
Definition: ruby.h:1094
static VALUE minmax_i(VALUE i, VALUE _memo, int argc, VALUE *argv)
Definition: enum.c:1290
static VALUE enum_min(VALUE obj)
Definition: enum.c:1173
static VALUE enum_none(VALUE obj)
Definition: enum.c:1110
VALUE rb_rescue2(VALUE(*b_proc)(ANYARGS), VALUE data1, VALUE(*r_proc)(ANYARGS), VALUE data2,...)
Definition: eval.c:701
#define INFINITY
Definition: missing.h:138
#define ENUMFUNC(name)
Definition: enum.c:953
static VALUE enum_one(VALUE obj)
Definition: enum.c:1074
VALUE rb_block_call_func(VALUE, VALUE, int, VALUE *)
Definition: ruby.h:1393
static VALUE enum_drop_while(VALUE obj)
Definition: enum.c:2219
#define enum_yield
Definition: enum.c:44
#define LONG2NUM(x)
Definition: ruby.h:1199
VALUE max_bv
Definition: enum.c:1507
int rb_respond_to(VALUE, ID)
Definition: vm_method.c:1564
VALUE last_bv
Definition: enum.c:1510
VALUE prev_elts
Definition: enum.c:2509
static ID id_call
Definition: enum.c:24
static VALUE zip_ary(VALUE val, NODE *memo, int argc, VALUE *argv)
Definition: enum.c:1933
static VALUE slicebefore_ii(VALUE i, VALUE _argp, int argc, VALUE *argv)
Definition: enum.c:2514
#define NEW_MEMO(a, b, c)
Definition: node.h:460
VALUE rb_ary_resize(VALUE ary, long len)
expands or shrinks ary to len elements.
Definition: array.c:1513
VALUE ary
Definition: enum.c:783
static VALUE enum_reject(VALUE obj)
Definition: enum.c:382
VALUE rb_enum_values_pack(int argc, VALUE *argv)
Definition: enum.c:33
VALUE rb_equal(VALUE, VALUE)
Definition: object.c:56
static VALUE enum_each_with_object(VALUE obj, VALUE memo)
Definition: enum.c:1923
int size
Definition: encoding.c:52
static ID id_div
Definition: enum.c:23
#define rb_check_arity(argc, min, max)
Definition: intern.h:277
#define INT2FIX(i)
Definition: ruby.h:241
static VALUE enum_partition(VALUE obj)
Definition: enum.c:651
static VALUE enum_to_a(int argc, VALUE *argv, VALUE obj)
Definition: enum.c:499
#define mul(x, y)
Definition: date_strftime.c:25
static VALUE enum_minmax_by(VALUE obj)
Definition: enum.c:1591
VALUE rb_block_proc(void)
Definition: proc.c:479
static VALUE enum_reverse_each(int argc, VALUE *argv, VALUE obj)
Definition: enum.c:1704
VALUE rb_check_array_type(VALUE ary)
Definition: array.c:557
VALUE min
Definition: enum.c:1508
VALUE rb_hash_aref(VALUE hash, VALUE key)
Definition: hash.c:560
#define RARRAY_PTR(a)
Definition: ruby.h:904
static VALUE member_i(VALUE iter, VALUE args, int argc, VALUE *argv)
Definition: enum.c:1612
long state
Definition: node.h:258
static VALUE enum_count(int argc, VALUE *argv, VALUE obj)
Definition: enum.c:151
static VALUE minmax_by_i(VALUE i, VALUE _memo, int argc, VALUE *argv)
Definition: enum.c:1536
#define LONG2FIX(i)
Definition: ruby.h:242
static VALUE each_slice_i(VALUE i, VALUE m, int argc, VALUE *argv)
Definition: enum.c:1767
#define RTEST(v)
Definition: ruby.h:445
void rb_thread_check_ints(void)
Definition: thread.c:1090
#define OBJ_INFECT(x, s)
Definition: ruby.h:1157
static VALUE enum_drop(VALUE obj, VALUE n)
Definition: enum.c:2170
v
Definition: win32ole.c:798
static VALUE enum_find(int argc, VALUE *argv, VALUE obj)
Definition: enum.c:212
VALUE rb_ary_dup(VALUE ary)
Definition: array.c:1778
static VALUE collect_all(VALUE i, VALUE ary, int argc, VALUE *argv)
Definition: enum.c:403
VALUE rb_cArray
Definition: array.c:29
VALUE rb_ary_concat(VALUE x, VALUE y)
Definition: array.c:3382
static VALUE enum_zip(int argc, VALUE *argv, VALUE obj)
Definition: enum.c:2033
static unsigned int hash(const char *str, unsigned int len)
Definition: lex.c:56
static ID id_next
Definition: enum.c:22
static VALUE enum_min_by(VALUE obj)
Definition: enum.c:1448
#define RETURN_ENUMERATOR(obj, argc, argv)
Definition: intern.h:220
VALUE rb_ary_new2(long capa)
Definition: array.c:417
#define ID2SYM(x)
Definition: ruby.h:363
const char * rb_id2name(ID id)
Definition: ripper.c:17005
static VALUE enum_flat_map(VALUE obj)
Definition: enum.c:476
static VALUE enum_each_cons_size(VALUE obj, VALUE args)
Definition: enum.c:1853
static VALUE enum_take_while(VALUE obj)
Definition: enum.c:2134
VALUE prev_elts
Definition: enum.c:2314
static VALUE enum_find_index(int argc, VALUE *argv, VALUE obj)
Definition: enum.c:278
static VALUE enum_minmax(VALUE obj)
Definition: enum.c:1388
void rb_warning(const char *fmt,...)
Definition: error.c:229
static VALUE separator
Definition: file.c:3974
#define CONST_ID(var, str)
Definition: ruby.h:1318
static VALUE call_stop(VALUE *v)
Definition: enum.c:1969
VALUE rb_define_module(const char *name)
Definition: class.c:617
static VALUE reject_i(VALUE i, VALUE ary, int argc, VALUE *argv)
Definition: enum.c:354
#define SYMBOL_P(x)
Definition: ruby.h:362
static VALUE enum_size(VALUE self, VALUE args)
Definition: enum.c:313
#define Qundef
Definition: ruby.h:436
VALUE rb_hash_aset(VALUE, VALUE, VALUE)
static VALUE enum_group_by(VALUE obj)
Definition: enum.c:699
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1344
VALUE buf
Definition: enum.c:784
static VALUE sort_by_i(VALUE i, VALUE _data, int argc, VALUE *argv)
Definition: enum.c:789
VALUE min
Definition: enum.c:1261
void rb_warn(const char *fmt,...)
Definition: error.c:216
ID rb_to_id(VALUE)
Definition: string.c:8154
#define bp()
Definition: vm_debug.h:27
static VALUE grep_iter_i(VALUE i, VALUE args, int argc, VALUE *argv)
Definition: enum.c:59
VALUE rb_eArgError
Definition: error.c:512
static ID cmp
Definition: compar.c:16
VALUE last
Definition: enum.c:1511
static VALUE inject_i(VALUE i, VALUE p, int argc, VALUE *argv)
Definition: enum.c:510
static VALUE call_next(VALUE *v)
Definition: enum.c:1963
#define NUM2LONG(x)
Definition: ruby.h:592
static VALUE find_index_i(VALUE i, VALUE memop, int argc, VALUE *argv)
Definition: enum.c:231
VALUE rb_attr_get(VALUE, ID)
Definition: variable.c:1122
#define id_eqq
Definition: enum.c:28
char ** argv
Definition: ruby.c:131
#define DBL2NUM(dbl)
Definition: ruby.h:837