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