Ruby  2.1.10p492(2016-04-01revision54464)
enumerator.c
Go to the documentation of this file.
1 /************************************************
2 
3  enumerator.c - provides Enumerator class
4 
5  $Author: nagachika $
6 
7  Copyright (C) 2001-2003 Akinori MUSHA
8 
9  $Idaemons: /home/cvs/rb/enumerator/enumerator.c,v 1.1.1.1 2001/07/15 10:12:48 knu Exp $
10  $RoughId: enumerator.c,v 1.6 2003/07/27 11:03:24 nobu Exp $
11  $Id: enumerator.c 46677 2014-07-03 15:46:17Z nagachika $
12 
13 ************************************************/
14 
15 #include "ruby/ruby.h"
16 #include "node.h"
17 #include "internal.h"
18 
19 /*
20  * Document-class: Enumerator
21  *
22  * A class which allows both internal and external iteration.
23  *
24  * An Enumerator can be created by the following methods.
25  * - Kernel#to_enum
26  * - Kernel#enum_for
27  * - Enumerator.new
28  *
29  * Most methods have two forms: a block form where the contents
30  * are evaluated for each item in the enumeration, and a non-block form
31  * which returns a new Enumerator wrapping the iteration.
32  *
33  * enumerator = %w(one two three).each
34  * puts enumerator.class # => Enumerator
35  *
36  * enumerator.each_with_object("foo") do |item, obj|
37  * puts "#{obj}: #{item}"
38  * end
39  *
40  * # foo: one
41  * # foo: two
42  * # foo: three
43  *
44  * enum_with_obj = enumerator.each_with_object("foo")
45  * puts enum_with_obj.class # => Enumerator
46  *
47  * enum_with_obj.each do |item, obj|
48  * puts "#{obj}: #{item}"
49  * end
50  *
51  * # foo: one
52  * # foo: two
53  * # foo: three
54  *
55  * This allows you to chain Enumerators together. For example, you
56  * can map a list's elements to strings containing the index
57  * and the element as a string via:
58  *
59  * puts %w[foo bar baz].map.with_index { |w, i| "#{i}:#{w}" }
60  * # => ["0:foo", "1:bar", "2:baz"]
61  *
62  * An Enumerator can also be used as an external iterator.
63  * For example, Enumerator#next returns the next value of the iterator
64  * or raises StopIteration if the Enumerator is at the end.
65  *
66  * e = [1,2,3].each # returns an enumerator object.
67  * puts e.next # => 1
68  * puts e.next # => 2
69  * puts e.next # => 3
70  * puts e.next # raises StopIteration
71  *
72  * You can use this to implement an internal iterator as follows:
73  *
74  * def ext_each(e)
75  * while true
76  * begin
77  * vs = e.next_values
78  * rescue StopIteration
79  * return $!.result
80  * end
81  * y = yield(*vs)
82  * e.feed y
83  * end
84  * end
85  *
86  * o = Object.new
87  *
88  * def o.each
89  * puts yield
90  * puts yield(1)
91  * puts yield(1, 2)
92  * 3
93  * end
94  *
95  * # use o.each as an internal iterator directly.
96  * puts o.each {|*x| puts x; [:b, *x] }
97  * # => [], [:b], [1], [:b, 1], [1, 2], [:b, 1, 2], 3
98  *
99  * # convert o.each to an external iterator for
100  * # implementing an internal iterator.
101  * puts ext_each(o.to_enum) {|*x| puts x; [:b, *x] }
102  * # => [], [:b], [1], [:b, 1], [1, 2], [:b, 1, 2], 3
103  *
104  */
110 
112 
113 struct enumerator {
124 };
125 
127 
128 struct generator {
130 };
131 
132 struct yielder {
134 };
135 
136 static VALUE generator_allocate(VALUE klass);
137 static VALUE generator_init(VALUE obj, VALUE proc);
138 
139 /*
140  * Enumerator
141  */
142 static void
144 {
145  struct enumerator *ptr = p;
146  rb_gc_mark(ptr->obj);
147  rb_gc_mark(ptr->args);
148  rb_gc_mark(ptr->fib);
149  rb_gc_mark(ptr->dst);
150  rb_gc_mark(ptr->lookahead);
151  rb_gc_mark(ptr->feedvalue);
152  rb_gc_mark(ptr->stop_exc);
153  rb_gc_mark(ptr->size);
154 }
155 
156 #define enumerator_free RUBY_TYPED_DEFAULT_FREE
157 
158 static size_t
159 enumerator_memsize(const void *p)
160 {
161  return p ? sizeof(struct enumerator) : 0;
162 }
163 
165  "enumerator",
166  {
170  },
172 };
173 
174 static struct enumerator *
176 {
177  struct enumerator *ptr;
178 
180  if (!ptr || ptr->obj == Qundef) {
181  rb_raise(rb_eArgError, "uninitialized enumerator");
182  }
183  return ptr;
184 }
185 
186 /*
187  * call-seq:
188  * obj.to_enum(method = :each, *args) -> enum
189  * obj.enum_for(method = :each, *args) -> enum
190  * obj.to_enum(method = :each, *args) {|*args| block} -> enum
191  * obj.enum_for(method = :each, *args){|*args| block} -> enum
192  *
193  * Creates a new Enumerator which will enumerate by calling +method+ on
194  * +obj+, passing +args+ if any.
195  *
196  * If a block is given, it will be used to calculate the size of
197  * the enumerator without the need to iterate it (see Enumerator#size).
198  *
199  * === Examples
200  *
201  * str = "xyz"
202  *
203  * enum = str.enum_for(:each_byte)
204  * enum.each { |b| puts b }
205  * # => 120
206  * # => 121
207  * # => 122
208  *
209  * # protect an array from being modified by some_method
210  * a = [1, 2, 3]
211  * some_method(a.to_enum)
212  *
213  * It is typical to call to_enum when defining methods for
214  * a generic Enumerable, in case no block is passed.
215  *
216  * Here is such an example, with parameter passing and a sizing block:
217  *
218  * module Enumerable
219  * # a generic method to repeat the values of any enumerable
220  * def repeat(n)
221  * raise ArgumentError, "#{n} is negative!" if n < 0
222  * unless block_given?
223  * return to_enum(__method__, n) do # __method__ is :repeat here
224  * sz = size # Call size and multiply by n...
225  * sz * n if sz # but return nil if size itself is nil
226  * end
227  * end
228  * each do |*val|
229  * n.times { yield *val }
230  * end
231  * end
232  * end
233  *
234  * %i[hello world].repeat(2) { |w| puts w }
235  * # => Prints 'hello', 'hello', 'world', 'world'
236  * enum = (1..14).repeat(3)
237  * # => returns an Enumerator when called without a block
238  * enum.first(4) # => [1, 1, 1, 2]
239  * enum.size # => 42
240  */
241 static VALUE
243 {
245 
246  if (argc > 0) {
247  --argc;
248  meth = *argv++;
249  }
251  if (rb_block_given_p()) {
253  }
254  return enumerator;
255 }
256 
257 static VALUE
259 {
260  struct enumerator *ptr;
261  VALUE enum_obj;
262 
263  enum_obj = TypedData_Make_Struct(klass, struct enumerator, &enumerator_data_type, ptr);
264  ptr->obj = Qundef;
265 
266  return enum_obj;
267 }
268 
269 static VALUE
271 {
272  struct enumerator *ptr;
273 
274  rb_check_frozen(enum_obj);
275  TypedData_Get_Struct(enum_obj, struct enumerator, &enumerator_data_type, ptr);
276 
277  if (!ptr) {
278  rb_raise(rb_eArgError, "unallocated enumerator");
279  }
280 
281  ptr->obj = obj;
282  ptr->meth = rb_to_id(meth);
283  if (argc) ptr->args = rb_ary_new4(argc, argv);
284  ptr->fib = 0;
285  ptr->dst = Qnil;
286  ptr->lookahead = Qundef;
287  ptr->feedvalue = Qundef;
288  ptr->stop_exc = Qfalse;
289  ptr->size = size;
290  ptr->size_fn = size_fn;
291 
292  return enum_obj;
293 }
294 
295 /*
296  * call-seq:
297  * Enumerator.new(size = nil) { |yielder| ... }
298  * Enumerator.new(obj, method = :each, *args)
299  *
300  * Creates a new Enumerator object, which can be used as an
301  * Enumerable.
302  *
303  * In the first form, iteration is defined by the given block, in
304  * which a "yielder" object, given as block parameter, can be used to
305  * yield a value by calling the +yield+ method (aliased as +<<+):
306  *
307  * fib = Enumerator.new do |y|
308  * a = b = 1
309  * loop do
310  * y << a
311  * a, b = b, a + b
312  * end
313  * end
314  *
315  * p fib.take(10) # => [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
316  *
317  * The optional parameter can be used to specify how to calculate the size
318  * in a lazy fashion (see Enumerator#size). It can either be a value or
319  * a callable object.
320  *
321  * In the second, deprecated, form, a generated Enumerator iterates over the
322  * given object using the given method with the given arguments passed.
323  *
324  * Use of this form is discouraged. Use Kernel#enum_for or Kernel#to_enum
325  * instead.
326  *
327  * e = Enumerator.new(ObjectSpace, :each_object)
328  * #-> ObjectSpace.enum_for(:each_object)
329  *
330  * e.select { |obj| obj.is_a?(Class) } #=> array of all classes
331  *
332  */
333 static VALUE
335 {
336  VALUE recv, meth = sym_each;
337  VALUE size = Qnil;
338 
339  if (rb_block_given_p()) {
340  rb_check_arity(argc, 0, 1);
342  if (argc) {
343  if (NIL_P(argv[0]) || rb_respond_to(argv[0], id_call) ||
344  (RB_TYPE_P(argv[0], T_FLOAT) && RFLOAT_VALUE(argv[0]) == INFINITY)) {
345  size = argv[0];
346  }
347  else {
348  size = rb_to_int(argv[0]);
349  }
350  argc = 0;
351  }
352  }
353  else {
355  rb_warn("Enumerator.new without a block is deprecated; use Object#to_enum");
356  recv = *argv++;
357  if (--argc) {
358  meth = *argv++;
359  --argc;
360  }
361  }
362 
363  return enumerator_init(obj, recv, meth, argc, argv, 0, size);
364 }
365 
366 /* :nodoc: */
367 static VALUE
369 {
370  struct enumerator *ptr0, *ptr1;
371 
372  if (!OBJ_INIT_COPY(obj, orig)) return obj;
373  ptr0 = enumerator_ptr(orig);
374  if (ptr0->fib) {
375  /* Fibers cannot be copied */
376  rb_raise(rb_eTypeError, "can't copy execution context");
377  }
378 
380 
381  if (!ptr1) {
382  rb_raise(rb_eArgError, "unallocated enumerator");
383  }
384 
385  ptr1->obj = ptr0->obj;
386  ptr1->meth = ptr0->meth;
387  ptr1->args = ptr0->args;
388  ptr1->fib = 0;
389  ptr1->lookahead = Qundef;
390  ptr1->feedvalue = Qundef;
391  ptr1->size = ptr0->size;
392  ptr1->size_fn = ptr0->size_fn;
393 
394  return obj;
395 }
396 
397 /*
398  * For backwards compatibility; use rb_enumeratorize_with_size
399  */
400 VALUE
402 {
404 }
405 
406 static VALUE
408 
409 VALUE
411 {
412  /* Similar effect as calling obj.to_enum, i.e. dispatching to either
413  Kernel#to_enum vs Lazy#to_enum */
415  return lazy_to_enum_i(obj, meth, argc, argv, size_fn);
416  else
418  obj, meth, argc, argv, size_fn, Qnil);
419 }
420 
421 static VALUE
423 {
424  int argc = 0;
425  VALUE *argv = 0;
426  const struct enumerator *e = enumerator_ptr(obj);
427  ID meth = e->meth;
428 
429  if (e->args) {
430  argc = RARRAY_LENINT(e->args);
431  argv = RARRAY_PTR(e->args);
432  }
433  return rb_block_call(e->obj, meth, argc, argv, func, arg);
434 }
435 
436 /*
437  * call-seq:
438  * enum.each { |elm| block } -> obj
439  * enum.each -> enum
440  * enum.each(*appending_args) { |elm| block } -> obj
441  * enum.each(*appending_args) -> an_enumerator
442  *
443  * Iterates over the block according to how this Enumerator was constructed.
444  * If no block and no arguments are given, returns self.
445  *
446  * === Examples
447  *
448  * "Hello, world!".scan(/\w+/) #=> ["Hello", "world"]
449  * "Hello, world!".to_enum(:scan, /\w+/).to_a #=> ["Hello", "world"]
450  * "Hello, world!".to_enum(:scan).each(/\w+/).to_a #=> ["Hello", "world"]
451  *
452  * obj = Object.new
453  *
454  * def obj.each_arg(a, b=:b, *rest)
455  * yield a
456  * yield b
457  * yield rest
458  * :method_returned
459  * end
460  *
461  * enum = obj.to_enum :each_arg, :a, :x
462  *
463  * enum.each.to_a #=> [:a, :x, []]
464  * enum.each.equal?(enum) #=> true
465  * enum.each { |elm| elm } #=> :method_returned
466  *
467  * enum.each(:y, :z).to_a #=> [:a, :x, [:y, :z]]
468  * enum.each(:y, :z).equal?(enum) #=> false
469  * enum.each(:y, :z) { |elm| elm } #=> :method_returned
470  *
471  */
472 static VALUE
474 {
475  if (argc > 0) {
476  struct enumerator *e = enumerator_ptr(obj = rb_obj_dup(obj));
477  VALUE args = e->args;
478  if (args) {
479 #if SIZEOF_INT < SIZEOF_LONG
480  /* check int range overflow */
482 #endif
483  args = rb_ary_dup(args);
485  }
486  else {
488  }
489  e->args = args;
490  }
491  if (!rb_block_given_p()) return obj;
492  return enumerator_block_call(obj, 0, obj);
493 }
494 
495 static VALUE
497 {
498  NODE *memo = (NODE *)m;
499  VALUE idx = memo->u1.value;
500  memo->u1.value = rb_int_succ(idx);
501 
502  if (argc <= 1)
503  return rb_yield_values(2, val, idx);
504 
505  return rb_yield_values(2, rb_ary_new4(argc, argv), idx);
506 }
507 
508 static VALUE
510 
511 static VALUE
513 {
514  return enumerator_size(obj);
515 }
516 
517 /*
518  * call-seq:
519  * e.with_index(offset = 0) {|(*args), idx| ... }
520  * e.with_index(offset = 0)
521  *
522  * Iterates the given block for each element with an index, which
523  * starts from +offset+. If no block is given, returns a new Enumerator
524  * that includes the index, starting from +offset+
525  *
526  * +offset+:: the starting index to use
527  *
528  */
529 static VALUE
531 {
532  VALUE memo;
533 
534  rb_scan_args(argc, argv, "01", &memo);
536  if (NIL_P(memo))
537  memo = INT2FIX(0);
538  else
539  memo = rb_to_int(memo);
541 }
542 
543 /*
544  * call-seq:
545  * e.each_with_index {|(*args), idx| ... }
546  * e.each_with_index
547  *
548  * Same as Enumerator#with_index(0), i.e. there is no starting offset.
549  *
550  * If no block is given, a new Enumerator is returned that includes the index.
551  *
552  */
553 static VALUE
555 {
556  return enumerator_with_index(0, NULL, obj);
557 }
558 
559 static VALUE
561 {
562  if (argc <= 1)
563  return rb_yield_values(2, val, memo);
564 
565  return rb_yield_values(2, rb_ary_new4(argc, argv), memo);
566 }
567 
568 /*
569  * call-seq:
570  * e.each_with_object(obj) {|(*args), obj| ... }
571  * e.each_with_object(obj)
572  * e.with_object(obj) {|(*args), obj| ... }
573  * e.with_object(obj)
574  *
575  * Iterates the given block for each element with an arbitrary object, +obj+,
576  * and returns +obj+
577  *
578  * If no block is given, returns a new Enumerator.
579  *
580  * === Example
581  *
582  * to_three = Enumerator.new do |y|
583  * 3.times do |x|
584  * y << x
585  * end
586  * end
587  *
588  * to_three_with_string = to_three.with_object("foo")
589  * to_three_with_string.each do |x,string|
590  * puts "#{string}: #{x}"
591  * end
592  *
593  * # => foo:0
594  * # => foo:1
595  * # => foo:2
596  */
597 static VALUE
599 {
602 
603  return memo;
604 }
605 
606 static VALUE
608 {
609  struct enumerator *e = enumerator_ptr(obj);
610  VALUE feedvalue = Qnil;
612  rb_fiber_yield(1, &args);
613  if (e->feedvalue != Qundef) {
614  feedvalue = e->feedvalue;
615  e->feedvalue = Qundef;
616  }
617  return feedvalue;
618 }
619 
620 static VALUE
622 {
623  struct enumerator *e = enumerator_ptr(obj);
624  VALUE nil = Qnil;
625  VALUE result;
626 
628  e->stop_exc = rb_exc_new2(rb_eStopIteration, "iteration reached an end");
630  return rb_fiber_yield(1, &nil);
631 }
632 
633 static void
635 {
636  VALUE curr = rb_fiber_current();
637  e->dst = curr;
638  e->fib = rb_fiber_new(next_i, obj);
639  e->lookahead = Qundef;
640 }
641 
642 static VALUE
644 {
645  VALUE curr, vs;
646 
647  if (e->stop_exc)
649 
650  curr = rb_fiber_current();
651 
652  if (!e->fib || !rb_fiber_alive_p(e->fib)) {
653  next_init(obj, e);
654  }
655 
656  vs = rb_fiber_resume(e->fib, 1, &curr);
657  if (e->stop_exc) {
658  e->fib = 0;
659  e->dst = Qnil;
660  e->lookahead = Qundef;
661  e->feedvalue = Qundef;
663  }
664  return vs;
665 }
666 
667 /*
668  * call-seq:
669  * e.next_values -> array
670  *
671  * Returns the next object as an array in the enumerator, and move the
672  * internal position forward. When the position reached at the end,
673  * StopIteration is raised.
674  *
675  * This method can be used to distinguish <code>yield</code> and <code>yield
676  * nil</code>.
677  *
678  * === Example
679  *
680  * o = Object.new
681  * def o.each
682  * yield
683  * yield 1
684  * yield 1, 2
685  * yield nil
686  * yield [1, 2]
687  * end
688  * e = o.to_enum
689  * p e.next_values
690  * p e.next_values
691  * p e.next_values
692  * p e.next_values
693  * p e.next_values
694  * e = o.to_enum
695  * p e.next
696  * p e.next
697  * p e.next
698  * p e.next
699  * p e.next
700  *
701  * ## yield args next_values next
702  * # yield [] nil
703  * # yield 1 [1] 1
704  * # yield 1, 2 [1, 2] [1, 2]
705  * # yield nil [nil] nil
706  * # yield [1, 2] [[1, 2]] [1, 2]
707  *
708  * Note that +next_values+ does not affect other non-external enumeration
709  * methods unless underlying iteration method itself has side-effect, e.g.
710  * IO#each_line.
711  *
712  */
713 
714 static VALUE
716 {
717  struct enumerator *e = enumerator_ptr(obj);
718  VALUE vs;
719 
720  if (e->lookahead != Qundef) {
721  vs = e->lookahead;
722  e->lookahead = Qundef;
723  return vs;
724  }
725 
726  return get_next_values(obj, e);
727 }
728 
729 static VALUE
730 ary2sv(VALUE args, int dup)
731 {
732  if (!RB_TYPE_P(args, T_ARRAY))
733  return args;
734 
735  switch (RARRAY_LEN(args)) {
736  case 0:
737  return Qnil;
738 
739  case 1:
740  return RARRAY_AREF(args, 0);
741 
742  default:
743  if (dup)
744  return rb_ary_dup(args);
745  return args;
746  }
747 }
748 
749 /*
750  * call-seq:
751  * e.next -> object
752  *
753  * Returns the next object in the enumerator, and move the internal position
754  * forward. When the position reached at the end, StopIteration is raised.
755  *
756  * === Example
757  *
758  * a = [1,2,3]
759  * e = a.to_enum
760  * p e.next #=> 1
761  * p e.next #=> 2
762  * p e.next #=> 3
763  * p e.next #raises StopIteration
764  *
765  * Note that enumeration sequence by +next+ does not affect other non-external
766  * enumeration methods, unless the underlying iteration methods itself has
767  * side-effect, e.g. IO#each_line.
768  *
769  */
770 
771 static VALUE
773 {
775  return ary2sv(vs, 0);
776 }
777 
778 static VALUE
780 {
781  struct enumerator *e = enumerator_ptr(obj);
782 
783  if (e->lookahead == Qundef) {
784  e->lookahead = get_next_values(obj, e);
785  }
786  return e->lookahead;
787 }
788 
789 /*
790  * call-seq:
791  * e.peek_values -> array
792  *
793  * Returns the next object as an array, similar to Enumerator#next_values, but
794  * doesn't move the internal position forward. If the position is already at
795  * the end, StopIteration is raised.
796  *
797  * === Example
798  *
799  * o = Object.new
800  * def o.each
801  * yield
802  * yield 1
803  * yield 1, 2
804  * end
805  * e = o.to_enum
806  * p e.peek_values #=> []
807  * e.next
808  * p e.peek_values #=> [1]
809  * p e.peek_values #=> [1]
810  * e.next
811  * p e.peek_values #=> [1, 2]
812  * e.next
813  * p e.peek_values # raises StopIteration
814  *
815  */
816 
817 static VALUE
819 {
821 }
822 
823 /*
824  * call-seq:
825  * e.peek -> object
826  *
827  * Returns the next object in the enumerator, but doesn't move the internal
828  * position forward. If the position is already at the end, StopIteration
829  * is raised.
830  *
831  * === Example
832  *
833  * a = [1,2,3]
834  * e = a.to_enum
835  * p e.next #=> 1
836  * p e.peek #=> 2
837  * p e.peek #=> 2
838  * p e.peek #=> 2
839  * p e.next #=> 2
840  * p e.next #=> 3
841  * p e.peek #raises StopIteration
842  *
843  */
844 
845 static VALUE
847 {
849  return ary2sv(vs, 1);
850 }
851 
852 /*
853  * call-seq:
854  * e.feed obj -> nil
855  *
856  * Sets the value to be returned by the next yield inside +e+.
857  *
858  * If the value is not set, the yield returns nil.
859  *
860  * This value is cleared after being yielded.
861  *
862  * # Array#map passes the array's elements to "yield" and collects the
863  * # results of "yield" as an array.
864  * # Following example shows that "next" returns the passed elements and
865  * # values passed to "feed" are collected as an array which can be
866  * # obtained by StopIteration#result.
867  * e = [1,2,3].map
868  * p e.next #=> 1
869  * e.feed "a"
870  * p e.next #=> 2
871  * e.feed "b"
872  * p e.next #=> 3
873  * e.feed "c"
874  * begin
875  * e.next
876  * rescue StopIteration
877  * p $!.result #=> ["a", "b", "c"]
878  * end
879  *
880  * o = Object.new
881  * def o.each
882  * x = yield # (2) blocks
883  * p x # (5) => "foo"
884  * x = yield # (6) blocks
885  * p x # (8) => nil
886  * x = yield # (9) blocks
887  * p x # not reached w/o another e.next
888  * end
889  *
890  * e = o.to_enum
891  * e.next # (1)
892  * e.feed "foo" # (3)
893  * e.next # (4)
894  * e.next # (7)
895  * # (10)
896  */
897 
898 static VALUE
900 {
901  struct enumerator *e = enumerator_ptr(obj);
902 
903  if (e->feedvalue != Qundef) {
904  rb_raise(rb_eTypeError, "feed value already set");
905  }
906  e->feedvalue = v;
907 
908  return Qnil;
909 }
910 
911 /*
912  * call-seq:
913  * e.rewind -> e
914  *
915  * Rewinds the enumeration sequence to the beginning.
916  *
917  * If the enclosed object responds to a "rewind" method, it is called.
918  */
919 
920 static VALUE
922 {
923  struct enumerator *e = enumerator_ptr(obj);
924 
925  rb_check_funcall(e->obj, id_rewind, 0, 0);
926 
927  e->fib = 0;
928  e->dst = Qnil;
929  e->lookahead = Qundef;
930  e->feedvalue = Qundef;
931  e->stop_exc = Qfalse;
932  return obj;
933 }
934 
935 static VALUE append_method(VALUE obj, VALUE str, ID default_method, VALUE default_args);
936 
937 static VALUE
939 {
940  struct enumerator *e;
941  VALUE eobj, str, cname;
942 
944 
945  cname = rb_obj_class(obj);
946 
947  if (!e || e->obj == Qundef) {
948  return rb_sprintf("#<%"PRIsVALUE": uninitialized>", rb_class_path(cname));
949  }
950 
951  if (recur) {
952  str = rb_sprintf("#<%"PRIsVALUE": ...>", rb_class_path(cname));
953  OBJ_TAINT(str);
954  return str;
955  }
956 
957  eobj = rb_attr_get(obj, id_receiver);
958  if (NIL_P(eobj)) {
959  eobj = e->obj;
960  }
961 
962  /* (1..100).each_cons(2) => "#<Enumerator: 1..100:each_cons(2)>" */
963  str = rb_sprintf("#<%"PRIsVALUE": %+"PRIsVALUE, rb_class_path(cname), eobj);
964  append_method(obj, str, e->meth, e->args);
965 
966  rb_str_buf_cat2(str, ">");
967 
968  return str;
969 }
970 
971 static VALUE
972 append_method(VALUE obj, VALUE str, ID default_method, VALUE default_args)
973 {
974  VALUE method, eargs;
975 
976  method = rb_attr_get(obj, id_method);
977  if (method != Qfalse) {
978  ID mid = default_method;
979  if (!NIL_P(method)) {
980  Check_Type(method, T_SYMBOL);
981  mid = SYM2ID(method);
982  }
983  rb_str_buf_cat2(str, ":");
984  rb_str_buf_append(str, rb_id2str(mid));
985  }
986 
987  eargs = rb_attr_get(obj, id_arguments);
988  if (NIL_P(eargs)) {
989  eargs = default_args;
990  }
991  if (eargs != Qfalse) {
992  long argc = RARRAY_LEN(eargs);
993  const VALUE *argv = RARRAY_CONST_PTR(eargs); /* WB: no new reference */
994 
995  if (argc > 0) {
996  rb_str_buf_cat2(str, "(");
997 
998  while (argc--) {
999  VALUE arg = *argv++;
1000 
1001  rb_str_append(str, rb_inspect(arg));
1002  rb_str_buf_cat2(str, argc > 0 ? ", " : ")");
1003  OBJ_INFECT(str, arg);
1004  }
1005  }
1006  }
1007 
1008  return str;
1009 }
1010 
1011 /*
1012  * call-seq:
1013  * e.inspect -> string
1014  *
1015  * Creates a printable version of <i>e</i>.
1016  */
1017 
1018 static VALUE
1020 {
1022 }
1023 
1024 /*
1025  * call-seq:
1026  * e.size -> int, Float::INFINITY or nil
1027  *
1028  * Returns the size of the enumerator, or +nil+ if it can't be calculated lazily.
1029  *
1030  * (1..100).to_a.permutation(4).size # => 94109400
1031  * loop.size # => Float::INFINITY
1032  * (1..100).drop_while.size # => nil
1033  */
1034 
1035 static VALUE
1037 {
1038  struct enumerator *e = enumerator_ptr(obj);
1039  int argc = 0;
1040  const VALUE *argv = NULL;
1041  VALUE size;
1042 
1043  if (e->size_fn) {
1044  return (*e->size_fn)(e->obj, e->args, obj);
1045  }
1046  if (e->args) {
1047  argc = (int)RARRAY_LEN(e->args);
1048  argv = RARRAY_CONST_PTR(e->args);
1049  }
1051  if (size != Qundef) return size;
1052  return e->size;
1053 }
1054 
1055 /*
1056  * Yielder
1057  */
1058 static void
1060 {
1061  struct yielder *ptr = p;
1062  rb_gc_mark(ptr->proc);
1063 }
1064 
1065 #define yielder_free RUBY_TYPED_DEFAULT_FREE
1066 
1067 static size_t
1068 yielder_memsize(const void *p)
1069 {
1070  return p ? sizeof(struct yielder) : 0;
1071 }
1072 
1074  "yielder",
1075  {
1076  yielder_mark,
1077  yielder_free,
1079  },
1081 };
1082 
1083 static struct yielder *
1085 {
1086  struct yielder *ptr;
1087 
1088  TypedData_Get_Struct(obj, struct yielder, &yielder_data_type, ptr);
1089  if (!ptr || ptr->proc == Qundef) {
1090  rb_raise(rb_eArgError, "uninitialized yielder");
1091  }
1092  return ptr;
1093 }
1094 
1095 /* :nodoc: */
1096 static VALUE
1098 {
1099  struct yielder *ptr;
1100  VALUE obj;
1101 
1102  obj = TypedData_Make_Struct(klass, struct yielder, &yielder_data_type, ptr);
1103  ptr->proc = Qundef;
1104 
1105  return obj;
1106 }
1107 
1108 static VALUE
1110 {
1111  struct yielder *ptr;
1112 
1113  TypedData_Get_Struct(obj, struct yielder, &yielder_data_type, ptr);
1114 
1115  if (!ptr) {
1116  rb_raise(rb_eArgError, "unallocated yielder");
1117  }
1118 
1119  ptr->proc = proc;
1120 
1121  return obj;
1122 }
1123 
1124 /* :nodoc: */
1125 static VALUE
1127 {
1128  rb_need_block();
1129 
1130  return yielder_init(obj, rb_block_proc());
1131 }
1132 
1133 /* :nodoc: */
1134 static VALUE
1136 {
1137  struct yielder *ptr = yielder_ptr(obj);
1138 
1139  return rb_proc_call(ptr->proc, args);
1140 }
1141 
1142 /* :nodoc: */
1144 {
1145  yielder_yield(obj, args);
1146  return obj;
1147 }
1148 
1149 static VALUE
1151 {
1152  return rb_yield_values2(argc, argv);
1153 }
1154 
1155 static VALUE
1157 {
1159 }
1160 
1161 /*
1162  * Generator
1163  */
1164 static void
1166 {
1167  struct generator *ptr = p;
1168  rb_gc_mark(ptr->proc);
1169 }
1170 
1171 #define generator_free RUBY_TYPED_DEFAULT_FREE
1172 
1173 static size_t
1174 generator_memsize(const void *p)
1175 {
1176  return p ? sizeof(struct generator) : 0;
1177 }
1178 
1180  "generator",
1181  {
1185  },
1187 };
1188 
1189 static struct generator *
1191 {
1192  struct generator *ptr;
1193 
1195  if (!ptr || ptr->proc == Qundef) {
1196  rb_raise(rb_eArgError, "uninitialized generator");
1197  }
1198  return ptr;
1199 }
1200 
1201 /* :nodoc: */
1202 static VALUE
1204 {
1205  struct generator *ptr;
1206  VALUE obj;
1207 
1208  obj = TypedData_Make_Struct(klass, struct generator, &generator_data_type, ptr);
1209  ptr->proc = Qundef;
1210 
1211  return obj;
1212 }
1213 
1214 static VALUE
1216 {
1217  struct generator *ptr;
1218 
1219  rb_check_frozen(obj);
1221 
1222  if (!ptr) {
1223  rb_raise(rb_eArgError, "unallocated generator");
1224  }
1225 
1226  ptr->proc = proc;
1227 
1228  return obj;
1229 }
1230 
1231 /* :nodoc: */
1232 static VALUE
1234 {
1235  VALUE proc;
1236 
1237  if (argc == 0) {
1238  rb_need_block();
1239 
1240  proc = rb_block_proc();
1241  }
1242  else {
1243  rb_scan_args(argc, argv, "1", &proc);
1244 
1245  if (!rb_obj_is_proc(proc))
1247  "wrong argument type %s (expected Proc)",
1249 
1250  if (rb_block_given_p()) {
1251  rb_warn("given block not used");
1252  }
1253  }
1254 
1255  return generator_init(obj, proc);
1256 }
1257 
1258 /* :nodoc: */
1259 static VALUE
1261 {
1262  struct generator *ptr0, *ptr1;
1263 
1264  if (!OBJ_INIT_COPY(obj, orig)) return obj;
1265 
1266  ptr0 = generator_ptr(orig);
1267 
1268  TypedData_Get_Struct(obj, struct generator, &generator_data_type, ptr1);
1269 
1270  if (!ptr1) {
1271  rb_raise(rb_eArgError, "unallocated generator");
1272  }
1273 
1274  ptr1->proc = ptr0->proc;
1275 
1276  return obj;
1277 }
1278 
1279 /* :nodoc: */
1280 static VALUE
1282 {
1283  struct generator *ptr = generator_ptr(obj);
1284  VALUE args = rb_ary_new2(argc + 1);
1285 
1286  rb_ary_push(args, yielder_new());
1287  if (argc > 0) {
1288  rb_ary_cat(args, argv, argc);
1289  }
1290 
1291  return rb_proc_call(ptr->proc, args);
1292 }
1293 
1294 /* Lazy Enumerator methods */
1295 static VALUE
1297 {
1298  VALUE r = rb_check_funcall(self, id_size, 0, 0);
1299  return (r == Qundef) ? Qnil : r;
1300 }
1301 
1302 static VALUE
1303 lazyenum_size(VALUE self, VALUE args, VALUE eobj)
1304 {
1305  return enum_size(self);
1306 }
1307 
1308 static VALUE
1310 {
1311  return enum_size(rb_ivar_get(self, id_receiver));
1312 }
1313 
1314 static VALUE
1316 {
1317  return lazy_size(lazy);
1318 }
1319 
1320 static VALUE
1322 {
1323  VALUE result;
1324  if (argc == 1) {
1325  VALUE args[2];
1326  args[0] = m;
1327  args[1] = val;
1328  result = rb_yield_values2(2, args);
1329  }
1330  else {
1331  VALUE args;
1332  int len = rb_long2int((long)argc + 1);
1333 
1334  args = rb_ary_tmp_new(len);
1335  rb_ary_push(args, m);
1336  if (argc > 0) {
1337  rb_ary_cat(args, argv, argc);
1338  }
1340  RB_GC_GUARD(args);
1341  }
1342  if (result == Qundef) rb_iter_break();
1343  return Qnil;
1344 }
1345 
1346 static VALUE
1348 {
1350  return Qnil;
1351 }
1352 
1353 /*
1354  * call-seq:
1355  * Lazy.new(obj, size=nil) { |yielder, *values| ... }
1356  *
1357  * Creates a new Lazy enumerator. When the enumerator is actually enumerated
1358  * (e.g. by calling #force), +obj+ will be enumerated and each value passed
1359  * to the given block. The block can yield values back using +yielder+.
1360  * For example, to create a method +filter_map+ in both lazy and
1361  * non-lazy fashions:
1362  *
1363  * module Enumerable
1364  * def filter_map(&block)
1365  * map(&block).compact
1366  * end
1367  * end
1368  *
1369  * class Enumerator::Lazy
1370  * def filter_map
1371  * Lazy.new(self) do |yielder, *values|
1372  * result = yield *values
1373  * yielder << result if result
1374  * end
1375  * end
1376  * end
1377  *
1378  * (1..Float::INFINITY).lazy.filter_map{|i| i*i if i.even?}.first(5)
1379  * # => [4, 16, 36, 64, 100]
1380  */
1381 static VALUE
1383 {
1384  VALUE obj, size = Qnil;
1385  VALUE generator;
1386 
1387  rb_check_arity(argc, 1, 2);
1388  if (!rb_block_given_p()) {
1389  rb_raise(rb_eArgError, "tried to call lazy new without a block");
1390  }
1391  obj = argv[0];
1392  if (argc > 1) {
1393  size = argv[1];
1394  }
1397  enumerator_init(self, generator, sym_each, 0, 0, 0, size);
1398  rb_ivar_set(self, id_receiver, obj);
1399 
1400  return self;
1401 }
1402 
1403 static VALUE
1405 {
1406  ID id = rb_frame_this_func();
1407  struct enumerator *e = enumerator_ptr(lazy);
1408  rb_ivar_set(lazy, id_method, ID2SYM(id));
1409  if (NIL_P(args)) {
1410  /* Qfalse indicates that the arguments are empty */
1412  }
1413  else {
1414  rb_ivar_set(lazy, id_arguments, args);
1415  }
1416  e->size_fn = size_fn;
1417  return lazy;
1418 }
1419 
1420 /*
1421  * call-seq:
1422  * e.lazy -> lazy_enumerator
1423  *
1424  * Returns a lazy enumerator, whose methods map/collect,
1425  * flat_map/collect_concat, select/find_all, reject, grep, zip, take,
1426  * take_while, drop, and drop_while enumerate values only on an
1427  * as-needed basis. However, if a block is given to zip, values
1428  * are enumerated immediately.
1429  *
1430  * === Example
1431  *
1432  * The following program finds pythagorean triples:
1433  *
1434  * def pythagorean_triples
1435  * (1..Float::INFINITY).lazy.flat_map {|z|
1436  * (1..z).flat_map {|x|
1437  * (x..z).select {|y|
1438  * x**2 + y**2 == z**2
1439  * }.map {|y|
1440  * [x, y, z]
1441  * }
1442  * }
1443  * }
1444  * end
1445  * # show first ten pythagorean triples
1446  * p pythagorean_triples.take(10).force # take is lazy, so force is needed
1447  * p pythagorean_triples.first(10) # first is eager
1448  * # show pythagorean triples less than 100
1449  * p pythagorean_triples.take_while { |*, z| z < 100 }.force
1450  */
1451 static VALUE
1453 {
1455  /* Qfalse indicates that the Enumerator::Lazy has no method name */
1457  return result;
1458 }
1459 
1460 static VALUE
1462 {
1464  obj, meth, argc, argv, size_fn, Qnil);
1465 }
1466 
1467 /*
1468  * call-seq:
1469  * lzy.to_enum(method = :each, *args) -> lazy_enum
1470  * lzy.enum_for(method = :each, *args) -> lazy_enum
1471  * lzy.to_enum(method = :each, *args) {|*args| block} -> lazy_enum
1472  * lzy.enum_for(method = :each, *args){|*args| block} -> lazy_enum
1473  *
1474  * Similar to Kernel#to_enum, except it returns a lazy enumerator.
1475  * This makes it easy to define Enumerable methods that will
1476  * naturally remain lazy if called from a lazy enumerator.
1477  *
1478  * For example, continuing from the example in Kernel#to_enum:
1479  *
1480  * # See Kernel#to_enum for the definition of repeat
1481  * r = 1..Float::INFINITY
1482  * r.repeat(2).first(5) # => [1, 1, 2, 2, 3]
1483  * r.repeat(2).class # => Enumerator
1484  * r.repeat(2).map{|n| n ** 2}.first(5) # => endless loop!
1485  * # works naturally on lazy enumerator:
1486  * r.lazy.repeat(2).class # => Enumerator::Lazy
1487  * r.lazy.repeat(2).map{|n| n ** 2}.first(5) # => [1, 1, 4, 4, 9]
1488  */
1489 
1490 static VALUE
1492 {
1493  VALUE lazy, meth = sym_each;
1494 
1495  if (argc > 0) {
1496  --argc;
1497  meth = *argv++;
1498  }
1499  lazy = lazy_to_enum_i(self, meth, argc, argv, 0);
1500  if (rb_block_given_p()) {
1501  enumerator_ptr(lazy)->size = rb_block_proc();
1502  }
1503  return lazy;
1504 }
1505 
1506 static VALUE
1508 {
1509  VALUE result = rb_yield_values2(argc - 1, &argv[1]);
1510 
1511  rb_funcall(argv[0], id_yield, 1, result);
1512  return Qnil;
1513 }
1514 
1515 static VALUE
1517 {
1518  if (!rb_block_given_p()) {
1519  rb_raise(rb_eArgError, "tried to call lazy map without a block");
1520  }
1521 
1523  lazy_map_func, 0),
1525 }
1526 
1527 static VALUE
1529 {
1530  return rb_funcall2(yielder, id_yield, argc, argv);
1531 }
1532 
1533 static VALUE
1535 {
1537  return Qnil;
1538 }
1539 
1540 static VALUE
1542 {
1543  VALUE ary = rb_check_array_type(obj);
1544  if (NIL_P(ary)) {
1546  }
1547  else {
1548  long i;
1549  for (i = 0; i < RARRAY_LEN(ary); i++) {
1550  rb_funcall(yielder, id_yield, 1, RARRAY_AREF(ary, i));
1551  }
1552  }
1553  return Qnil;
1554 }
1555 
1556 static VALUE
1558 {
1559  VALUE result = rb_yield_values2(argc - 1, &argv[1]);
1560  if (RB_TYPE_P(result, T_ARRAY)) {
1561  long i;
1562  for (i = 0; i < RARRAY_LEN(result); i++) {
1563  rb_funcall(argv[0], id_yield, 1, RARRAY_AREF(result, i));
1564  }
1565  }
1566  else {
1569  }
1570  else {
1572  }
1573  }
1574  return Qnil;
1575 }
1576 
1577 /*
1578  * call-seq:
1579  * lazy.collect_concat { |obj| block } -> a_lazy_enumerator
1580  * lazy.flat_map { |obj| block } -> a_lazy_enumerator
1581  *
1582  * Returns a new lazy enumerator with the concatenated results of running
1583  * <i>block</i> once for every element in <i>lazy</i>.
1584  *
1585  * ["foo", "bar"].lazy.flat_map {|i| i.each_char.lazy}.force
1586  * #=> ["f", "o", "o", "b", "a", "r"]
1587  *
1588  * A value <i>x</i> returned by <i>block</i> is decomposed if either of
1589  * the following conditions is true:
1590  *
1591  * a) <i>x</i> responds to both each and force, which means that
1592  * <i>x</i> is a lazy enumerator.
1593  * b) <i>x</i> is an array or responds to to_ary.
1594  *
1595  * Otherwise, <i>x</i> is contained as-is in the return value.
1596  *
1597  * [{a:1}, {b:2}].lazy.flat_map {|i| i}.force
1598  * #=> [{:a=>1}, {:b=>2}]
1599  */
1600 static VALUE
1602 {
1603  if (!rb_block_given_p()) {
1604  rb_raise(rb_eArgError, "tried to call lazy flat_map without a block");
1605  }
1606 
1608  lazy_flat_map_func, 0),
1609  Qnil, 0);
1610 }
1611 
1612 static VALUE
1614 {
1615  VALUE element = rb_enum_values_pack(argc - 1, argv + 1);
1616 
1617  if (RTEST(rb_yield(element))) {
1618  return rb_funcall(argv[0], id_yield, 1, element);
1619  }
1620  return Qnil;
1621 }
1622 
1623 static VALUE
1625 {
1626  if (!rb_block_given_p()) {
1627  rb_raise(rb_eArgError, "tried to call lazy select without a block");
1628  }
1629 
1631  lazy_select_func, 0),
1632  Qnil, 0);
1633 }
1634 
1635 static VALUE
1637 {
1638  VALUE element = rb_enum_values_pack(argc - 1, argv + 1);
1639 
1640  if (!RTEST(rb_yield(element))) {
1641  return rb_funcall(argv[0], id_yield, 1, element);
1642  }
1643  return Qnil;
1644 }
1645 
1646 static VALUE
1648 {
1649  if (!rb_block_given_p()) {
1650  rb_raise(rb_eArgError, "tried to call lazy reject without a block");
1651  }
1652 
1654  lazy_reject_func, 0),
1655  Qnil, 0);
1656 }
1657 
1658 static VALUE
1660 {
1661  VALUE i = rb_enum_values_pack(argc - 1, argv + 1);
1662  VALUE result = rb_funcall(m, id_eqq, 1, i);
1663 
1664  if (RTEST(result)) {
1665  rb_funcall(argv[0], id_yield, 1, i);
1666  }
1667  return Qnil;
1668 }
1669 
1670 static VALUE
1672 {
1673  VALUE i = rb_enum_values_pack(argc - 1, argv + 1);
1674  VALUE result = rb_funcall(m, id_eqq, 1, i);
1675 
1676  if (RTEST(result)) {
1677  rb_funcall(argv[0], id_yield, 1, rb_yield(i));
1678  }
1679  return Qnil;
1680 }
1681 
1682 static VALUE
1684 {
1686  rb_block_given_p() ?
1688  pattern),
1689  rb_ary_new3(1, pattern), 0);
1690 }
1691 
1692 static VALUE
1694 {
1695  return rb_funcall(obj, id_next, 0);
1696 }
1697 
1698 static VALUE
1700 {
1701  return Qnil;
1702 }
1703 
1704 static VALUE
1706 {
1707  VALUE yielder, ary, memo;
1708  long i, count;
1709 
1710  yielder = argv[0];
1711  memo = rb_attr_get(yielder, id_memo);
1712  count = NIL_P(memo) ? 0 : NUM2LONG(memo);
1713 
1714  ary = rb_ary_new2(RARRAY_LEN(arrays) + 1);
1715  rb_ary_push(ary, argv[1]);
1716  for (i = 0; i < RARRAY_LEN(arrays); i++) {
1717  rb_ary_push(ary, rb_ary_entry(RARRAY_AREF(arrays, i), count));
1718  }
1719  rb_funcall(yielder, id_yield, 1, ary);
1721  return Qnil;
1722 }
1723 
1724 static VALUE
1726 {
1727  VALUE yielder, ary, arg, v;
1728  long i;
1729 
1730  yielder = argv[0];
1731  arg = rb_attr_get(yielder, id_memo);
1732  if (NIL_P(arg)) {
1733  arg = rb_ary_new2(RARRAY_LEN(zip_args));
1734  for (i = 0; i < RARRAY_LEN(zip_args); i++) {
1735  rb_ary_push(arg, rb_funcall(RARRAY_AREF(zip_args, i), id_to_enum, 0));
1736  }
1737  rb_ivar_set(yielder, id_memo, arg);
1738  }
1739 
1740  ary = rb_ary_new2(RARRAY_LEN(arg) + 1);
1741  v = Qnil;
1742  if (--argc > 0) {
1743  ++argv;
1744  v = argc > 1 ? rb_ary_new_from_values(argc, argv) : *argv;
1745  }
1746  rb_ary_push(ary, v);
1747  for (i = 0; i < RARRAY_LEN(arg); i++) {
1748  v = rb_rescue2(call_next, RARRAY_AREF(arg, i), next_stopped, 0,
1749  rb_eStopIteration, (VALUE)0);
1750  rb_ary_push(ary, v);
1751  }
1752  rb_funcall(yielder, id_yield, 1, ary);
1753  return Qnil;
1754 }
1755 
1756 static VALUE
1758 {
1759  VALUE ary, v;
1760  long i;
1762 
1763  if (rb_block_given_p()) {
1764  return rb_call_super(argc, argv);
1765  }
1766 
1767  ary = rb_ary_new2(argc);
1768  for (i = 0; i < argc; i++) {
1769  v = rb_check_array_type(argv[i]);
1770  if (NIL_P(v)) {
1771  for (; i < argc; i++) {
1772  if (!rb_respond_to(argv[i], id_each)) {
1773  rb_raise(rb_eTypeError, "wrong argument type %s (must respond to :each)",
1774  rb_obj_classname(argv[i]));
1775  }
1776  }
1777  ary = rb_ary_new4(argc, argv);
1778  func = lazy_zip_func;
1779  break;
1780  }
1781  rb_ary_push(ary, v);
1782  }
1783 
1785  func, ary),
1786  ary, lazy_receiver_size);
1787 }
1788 
1789 static VALUE
1791 {
1792  long remain;
1793  VALUE memo = rb_attr_get(argv[0], id_memo);
1794  if (NIL_P(memo)) {
1795  memo = args;
1796  }
1797 
1798  rb_funcall2(argv[0], id_yield, argc - 1, argv + 1);
1799  if ((remain = NUM2LONG(memo)-1) == 0) {
1800  return Qundef;
1801  }
1802  else {
1803  rb_ivar_set(argv[0], id_memo, LONG2NUM(remain));
1804  return Qnil;
1805  }
1806 }
1807 
1808 static VALUE
1810 {
1811  VALUE receiver = lazy_size(lazy);
1812  long len = NUM2LONG(RARRAY_AREF(rb_ivar_get(lazy, id_arguments), 0));
1813  if (NIL_P(receiver) || (FIXNUM_P(receiver) && FIX2LONG(receiver) < len))
1814  return receiver;
1815  return LONG2NUM(len);
1816 }
1817 
1818 static VALUE
1820 {
1821  long len = NUM2LONG(n);
1822  VALUE lazy;
1823 
1824  if (len < 0) {
1825  rb_raise(rb_eArgError, "attempt to take negative size");
1826  }
1827  if (len == 0) {
1828  VALUE len = INT2FIX(0);
1829  lazy = lazy_to_enum_i(obj, sym_cycle, 1, &len, 0);
1830  }
1831  else {
1832  lazy = rb_block_call(rb_cLazy, id_new, 1, &obj,
1833  lazy_take_func, n);
1834  }
1835  return lazy_set_method(lazy, rb_ary_new3(1, n), lazy_take_size);
1836 }
1837 
1838 static VALUE
1840 {
1841  VALUE result = rb_yield_values2(argc - 1, &argv[1]);
1842  if (!RTEST(result)) return Qundef;
1843  rb_funcall2(argv[0], id_yield, argc - 1, argv + 1);
1844  return Qnil;
1845 }
1846 
1847 static VALUE
1849 {
1850  if (!rb_block_given_p()) {
1851  rb_raise(rb_eArgError, "tried to call lazy take_while without a block");
1852  }
1855  Qnil, 0);
1856 }
1857 
1858 static VALUE
1860 {
1861  long len = NUM2LONG(RARRAY_AREF(rb_ivar_get(lazy, id_arguments), 0));
1862  VALUE receiver = lazy_size(lazy);
1863  if (NIL_P(receiver))
1864  return receiver;
1865  if (FIXNUM_P(receiver)) {
1866  len = FIX2LONG(receiver) - len;
1867  return LONG2FIX(len < 0 ? 0 : len);
1868  }
1869  return rb_funcall(receiver, '-', 1, LONG2NUM(len));
1870 }
1871 
1872 static VALUE
1874 {
1875  long remain;
1876  VALUE memo = rb_attr_get(argv[0], id_memo);
1877  if (NIL_P(memo)) {
1878  memo = args;
1879  }
1880  if ((remain = NUM2LONG(memo)) == 0) {
1881  rb_funcall2(argv[0], id_yield, argc - 1, argv + 1);
1882  }
1883  else {
1884  rb_ivar_set(argv[0], id_memo, LONG2NUM(--remain));
1885  }
1886  return Qnil;
1887 }
1888 
1889 static VALUE
1891 {
1892  long len = NUM2LONG(n);
1893 
1894  if (len < 0) {
1895  rb_raise(rb_eArgError, "attempt to drop negative size");
1896  }
1898  lazy_drop_func, n),
1899  rb_ary_new3(1, n), lazy_drop_size);
1900 }
1901 
1902 static VALUE
1904 {
1905  VALUE memo = rb_attr_get(argv[0], id_memo);
1906  if (NIL_P(memo) && !RTEST(rb_yield_values2(argc - 1, &argv[1]))) {
1907  rb_ivar_set(argv[0], id_memo, memo = Qtrue);
1908  }
1909  if (memo == Qtrue) {
1910  rb_funcall2(argv[0], id_yield, argc - 1, argv + 1);
1911  }
1912  return Qnil;
1913 }
1914 
1915 static VALUE
1917 {
1918  if (!rb_block_given_p()) {
1919  rb_raise(rb_eArgError, "tried to call lazy drop_while without a block");
1920  }
1923  Qnil, 0);
1924 }
1925 
1926 static VALUE
1928 {
1930 }
1931 
1932 static VALUE
1934 {
1935  return obj;
1936 }
1937 
1938 /*
1939  * Document-class: StopIteration
1940  *
1941  * Raised to stop the iteration, in particular by Enumerator#next. It is
1942  * rescued by Kernel#loop.
1943  *
1944  * loop do
1945  * puts "Hello"
1946  * raise StopIteration
1947  * puts "World"
1948  * end
1949  * puts "Done!"
1950  *
1951  * <em>produces:</em>
1952  *
1953  * Hello
1954  * Done!
1955  */
1956 
1957 /*
1958  * call-seq:
1959  * result -> value
1960  *
1961  * Returns the return value of the iterator.
1962  *
1963  * o = Object.new
1964  * def o.each
1965  * yield 1
1966  * yield 2
1967  * yield 3
1968  * 100
1969  * end
1970  *
1971  * e = o.to_enum
1972  *
1973  * puts e.next #=> 1
1974  * puts e.next #=> 2
1975  * puts e.next #=> 3
1976  *
1977  * begin
1978  * e.next
1979  * rescue StopIteration => ex
1980  * puts ex.result #=> 100
1981  * end
1982  *
1983  */
1984 
1985 static VALUE
1987 {
1988  return rb_attr_get(self, id_result);
1989 }
1990 
1991 void
1993 {
1994  rb_define_method(rb_mKernel, "to_enum", obj_to_enum, -1);
1995  rb_define_method(rb_mKernel, "enum_for", obj_to_enum, -1);
1996 
1997  rb_cEnumerator = rb_define_class("Enumerator", rb_cObject);
1999 
2002  rb_define_method(rb_cEnumerator, "initialize_copy", enumerator_init_copy, 1);
2005  rb_define_method(rb_cEnumerator, "each_with_object", enumerator_with_object, 1);
2016 
2017  /* Lazy */
2020  rb_define_method(rb_cLazy, "initialize", lazy_initialize, -1);
2021  rb_define_method(rb_cLazy, "to_enum", lazy_to_enum, -1);
2022  rb_define_method(rb_cLazy, "enum_for", lazy_to_enum, -1);
2023  rb_define_method(rb_cLazy, "map", lazy_map, 0);
2024  rb_define_method(rb_cLazy, "collect", lazy_map, 0);
2025  rb_define_method(rb_cLazy, "flat_map", lazy_flat_map, 0);
2026  rb_define_method(rb_cLazy, "collect_concat", lazy_flat_map, 0);
2027  rb_define_method(rb_cLazy, "select", lazy_select, 0);
2028  rb_define_method(rb_cLazy, "find_all", lazy_select, 0);
2029  rb_define_method(rb_cLazy, "reject", lazy_reject, 0);
2030  rb_define_method(rb_cLazy, "grep", lazy_grep, 1);
2031  rb_define_method(rb_cLazy, "zip", lazy_zip, -1);
2032  rb_define_method(rb_cLazy, "take", lazy_take, 1);
2033  rb_define_method(rb_cLazy, "take_while", lazy_take_while, 0);
2034  rb_define_method(rb_cLazy, "drop", lazy_drop, 1);
2035  rb_define_method(rb_cLazy, "drop_while", lazy_drop_while, 0);
2036  rb_define_method(rb_cLazy, "lazy", lazy_lazy, 0);
2037  rb_define_method(rb_cLazy, "chunk", lazy_super, -1);
2038  rb_define_method(rb_cLazy, "slice_before", lazy_super, -1);
2039 
2040  rb_define_alias(rb_cLazy, "force", "to_a");
2041 
2042  rb_eStopIteration = rb_define_class("StopIteration", rb_eIndexError);
2044 
2045  /* Generator */
2050  rb_define_method(rb_cGenerator, "initialize_copy", generator_init_copy, 1);
2052 
2053  /* Yielder */
2056  rb_define_method(rb_cYielder, "initialize", yielder_initialize, 0);
2059 
2060  rb_provide("enumerator.so"); /* for backward compatibility */
2061 }
2062 
2063 void
2065 {
2066  id_rewind = rb_intern("rewind");
2067  id_each = rb_intern("each");
2068  id_call = rb_intern("call");
2069  id_size = rb_intern("size");
2070  id_yield = rb_intern("yield");
2071  id_new = rb_intern("new");
2072  id_initialize = rb_intern("initialize");
2073  id_next = rb_intern("next");
2074  id_result = rb_intern("result");
2075  id_lazy = rb_intern("lazy");
2076  id_eqq = rb_intern("===");
2077  id_receiver = rb_intern("receiver");
2078  id_arguments = rb_intern("arguments");
2079  id_memo = rb_intern("memo");
2080  id_method = rb_intern("method");
2081  id_force = rb_intern("force");
2082  id_to_enum = rb_intern("to_enum");
2083  sym_each = ID2SYM(id_each);
2084  sym_cycle = ID2SYM(rb_intern("cycle"));
2085 
2086  InitVM(Enumerator);
2087 }
static VALUE append_method(VALUE obj, VALUE str, ID default_method, VALUE default_args)
Definition: enumerator.c:972
static VALUE lazy_drop(VALUE obj, VALUE n)
Definition: enumerator.c:1890
static VALUE next_ii(RB_BLOCK_CALL_FUNC_ARGLIST(i, obj))
Definition: enumerator.c:607
#define T_SYMBOL
Definition: ruby.h:494
VALUE size
Definition: enumerator.c:122
static VALUE lazy_zip_func(RB_BLOCK_CALL_FUNC_ARGLIST(val, zip_args))
Definition: enumerator.c:1725
static void enumerator_mark(void *p)
Definition: enumerator.c:143
#define rb_exc_new2
Definition: intern.h:247
VALUE rb_ary_entry(VALUE ary, long offset)
Definition: array.c:1179
static VALUE next_i(VALUE curr, VALUE obj)
Definition: enumerator.c:621
#define RARRAY_LEN(a)
Definition: ruby.h:878
#define RUBY_TYPED_FREE_IMMEDIATELY
Definition: ruby.h:1015
static VALUE rb_cGenerator
Definition: enumerator.c:126
static VALUE sym_cycle
Definition: enumerator.c:109
static VALUE enumerator_rewind(VALUE obj)
Definition: enumerator.c:921
static VALUE lazy_reject(VALUE obj)
Definition: enumerator.c:1647
static VALUE lazy_grep(VALUE obj, VALUE pattern)
Definition: enumerator.c:1683
VALUE rb_id2str(ID id)
Definition: ripper.c:17201
VALUE rb_yield_values(int n,...)
Definition: vm_eval.c:959
int count
Definition: encoding.c:48
static VALUE call_next(VALUE obj)
Definition: enumerator.c:1693
static void generator_mark(void *p)
Definition: enumerator.c:1165
static VALUE enumerator_peek_values(VALUE obj)
Definition: enumerator.c:779
static VALUE yielder_new(void)
Definition: enumerator.c:1156
static VALUE generator_init_copy(VALUE obj, VALUE orig)
Definition: enumerator.c:1260
static size_t generator_memsize(const void *p)
Definition: enumerator.c:1174
VALUE feedvalue
Definition: enumerator.c:120
#define InitVM(ext)
Definition: ruby.h:1797
static VALUE enumerator_enum_size(VALUE obj, VALUE args, VALUE eobj)
Definition: enumerator.c:512
#define Qtrue
Definition: ruby.h:426
VALUE rb_enumerator_size_func(VALUE, VALUE, VALUE)
Definition: intern.h:231
static VALUE yielder_allocate(VALUE klass)
Definition: enumerator.c:1097
#define OBJ_INIT_COPY(obj, orig)
Definition: intern.h:287
#define TypedData_Get_Struct(obj, type, data_type, sval)
Definition: ruby.h:1041
static VALUE lazy_size(VALUE self)
Definition: enumerator.c:1309
static VALUE yielder_init(VALUE obj, VALUE proc)
Definition: enumerator.c:1109
static VALUE enumerator_init(VALUE enum_obj, VALUE obj, VALUE meth, int argc, VALUE *argv, rb_enumerator_size_func *size_fn, VALUE size)
Definition: enumerator.c:270
ID rb_frame_this_func(void)
Definition: eval.c:943
VALUE rb_eTypeError
Definition: error.c:548
#define rb_check_arity
Definition: intern.h:296
static VALUE lazy_zip_arrays_func(RB_BLOCK_CALL_FUNC_ARGLIST(val, arrays))
Definition: enumerator.c:1705
VALUE rb_ary_push(VALUE ary, VALUE item)
Definition: array.c:900
#define rb_long2int(n)
Definition: ruby.h:317
SSL_METHOD *(* func)(void)
Definition: ossl_ssl.c:113
#define SYM2ID(x)
Definition: ruby.h:356
VALUE rb_fiber_yield(int argc, VALUE *argv)
Definition: cont.c:1505
static const rb_data_type_t generator_data_type
Definition: enumerator.c:1179
VALUE rb_ary_tmp_new(long capa)
Definition: array.c:538
VALUE rb_enumeratorize_with_size(VALUE obj, VALUE meth, int argc, VALUE *argv, rb_enumerator_size_func *size_fn)
Definition: enumerator.c:410
VALUE rb_funcall(VALUE, ID, int,...)
Calls a method.
Definition: vm_eval.c:781
static VALUE enumerator_next_values(VALUE obj)
Definition: enumerator.c:715
VALUE rb_cEnumerator
Definition: enumerator.c:105
VALUE rb_fiber_alive_p(VALUE fibval)
Definition: cont.c:1533
VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super)
Defines a class under the namespace of outer.
Definition: class.c:657
VALUE rb_to_int(VALUE)
Definition: object.c:2700
#define Check_Type(v, t)
Definition: ruby.h:532
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:1857
VALUE obj
Definition: enumerator.c:114
VALUE rb_ivar_get(VALUE, ID)
Definition: variable.c:1115
VALUE rb_fiber_current(void)
Definition: cont.c:1341
static const rb_data_type_t yielder_data_type
Definition: enumerator.c:1073
VALUE rb_exec_recursive(VALUE(*)(VALUE, VALUE, int), VALUE, VALUE)
Definition: thread.c:4992
#define RB_GC_GUARD(v)
Definition: ruby.h:523
void rb_define_alloc_func(VALUE, rb_alloc_func_t)
VALUE proc
Definition: enumerator.c:129
VALUE rb_obj_is_kind_of(VALUE, VALUE)
Definition: object.c:646
static VALUE enum_size(VALUE self)
Definition: enumerator.c:1296
static VALUE lazy_flat_map_func(RB_BLOCK_CALL_FUNC_ARGLIST(val, m))
Definition: enumerator.c:1557
#define generator_free
Definition: enumerator.c:1171
static VALUE enumerator_next(VALUE obj)
Definition: enumerator.c:772
void rb_include_module(VALUE klass, VALUE module)
Definition: class.c:808
static VALUE enumerator_block_call(VALUE obj, rb_block_call_func *func, VALUE arg)
Definition: enumerator.c:422
VALUE rb_block_call(VALUE, ID, int, const VALUE *, rb_block_call_func_t, VALUE)
void rb_gc_mark(VALUE ptr)
Definition: gc.c:3607
static ID id_lazy
Definition: enumerator.c:108
#define T_ARRAY
Definition: ruby.h:484
static VALUE lazy_init_iterator(RB_BLOCK_CALL_FUNC_ARGLIST(val, m))
Definition: enumerator.c:1321
static VALUE lazy_to_enum(int argc, VALUE *argv, VALUE self)
Definition: enumerator.c:1491
#define FIXNUM_P(f)
Definition: ruby.h:347
static VALUE yielder_yield(VALUE obj, VALUE args)
Definition: enumerator.c:1135
VALUE rb_str_buf_append(VALUE, VALUE)
Definition: string.c:2281
static VALUE generator_initialize(int argc, VALUE *argv, VALUE obj)
Definition: enumerator.c:1233
static VALUE generator_allocate(VALUE klass)
Definition: enumerator.c:1203
static ID id_memo
Definition: enumerator.c:108
const char * rb_obj_classname(VALUE)
Definition: variable.c:406
#define rb_ary_new2
Definition: intern.h:90
static VALUE enumerator_with_object(VALUE obj, VALUE memo)
Definition: enumerator.c:598
void InitVM_Enumerator(void)
Definition: enumerator.c:1992
rb_enumerator_size_func * size_fn
Definition: enumerator.c:123
static VALUE lazy_flat_map(VALUE obj)
Definition: enumerator.c:1601
Definition: node.h:239
#define RB_BLOCK_CALL_FUNC_ARGLIST(yielded_arg, callback_arg)
Definition: ruby.h:1519
VALUE rb_enumeratorize(VALUE obj, VALUE meth, int argc, VALUE *argv)
Definition: enumerator.c:401
void rb_exc_raise(VALUE mesg)
Definition: eval.c:567
static VALUE lazy_map(VALUE obj)
Definition: enumerator.c:1516
static ID id_initialize
Definition: enumerator.c:107
static struct enumerator * enumerator_ptr(VALUE obj)
Definition: enumerator.c:175
VALUE rb_obj_dup(VALUE)
Definition: object.c:406
#define RB_TYPE_P(obj, type)
Definition: ruby.h:1672
static VALUE enumerable_lazy(VALUE obj)
Definition: enumerator.c:1452
VALUE rb_block_call_func(RB_BLOCK_CALL_FUNC_ARGLIST(yielded_arg, callback_arg))
Definition: ruby.h:1521
void rb_iter_break(void)
Definition: vm.c:1154
static ID id_to_enum
Definition: enumerator.c:107
static VALUE get_next_values(VALUE obj, struct enumerator *e)
Definition: enumerator.c:643
static VALUE lazy_flat_map_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, yielder))
Definition: enumerator.c:1528
VALUE rb_fiber_resume(VALUE fibval, int argc, VALUE *argv)
Definition: cont.c:1489
static VALUE lazy_drop_while_func(RB_BLOCK_CALL_FUNC_ARGLIST(val, args))
Definition: enumerator.c:1903
static VALUE enumerator_each(int argc, VALUE *argv, VALUE obj)
Definition: enumerator.c:473
static VALUE enumerator_with_index(int argc, VALUE *argv, VALUE obj)
Definition: enumerator.c:530
int rb_block_given_p(void)
Definition: eval.c:712
static VALUE obj_to_enum(int argc, VALUE *argv, VALUE obj)
Definition: enumerator.c:242
VALUE rb_ary_cat(VALUE ary, const VALUE *ptr, long len)
Definition: array.c:911
#define val
RUBY_EXTERN VALUE rb_cObject
Definition: ruby.h:1561
static VALUE lazy_take_func(RB_BLOCK_CALL_FUNC_ARGLIST(val, args))
Definition: enumerator.c:1790
static VALUE lazyenum_size(VALUE self, VALUE args, VALUE eobj)
Definition: enumerator.c:1303
VALUE rb_str_buf_cat2(VALUE, const char *)
Definition: string.c:2133
static VALUE lazy_to_enum_i(VALUE self, VALUE meth, int argc, VALUE *argv, rb_enumerator_size_func *size_fn)
Definition: enumerator.c:1461
static ID id_next
Definition: enumerator.c:108
RUBY_EXTERN VALUE rb_mKernel
Definition: ruby.h:1549
static VALUE enumerator_peek_values_m(VALUE obj)
Definition: enumerator.c:818
#define NIL_P(v)
Definition: ruby.h:438
static VALUE enumerator_size(VALUE obj)
Definition: enumerator.c:1036
VALUE rb_define_class(const char *name, VALUE super)
Defines a top-level class.
Definition: class.c:611
static void next_init(VALUE obj, struct enumerator *e)
Definition: enumerator.c:634
static VALUE lazy_take_size(VALUE generator, VALUE args, VALUE lazy)
Definition: enumerator.c:1809
VALUE value
Definition: node.h:245
VALUE proc
Definition: enumerator.c:133
union RNode::@129 u1
VALUE rb_fiber_new(VALUE(*func)(ANYARGS), VALUE obj)
Definition: cont.c:1231
#define T_FLOAT
Definition: ruby.h:481
static VALUE stop_result(VALUE self)
Definition: enumerator.c:1986
int argc
Definition: ruby.c:131
#define Qfalse
Definition: ruby.h:425
static VALUE lazy_init_block_i(RB_BLOCK_CALL_FUNC_ARGLIST(val, m))
Definition: enumerator.c:1347
static VALUE lazy_take_while(VALUE obj)
Definition: enumerator.c:1848
static VALUE lazy_select(VALUE obj)
Definition: enumerator.c:1624
VALUE rb_cLazy
Definition: enumerator.c:106
#define rb_ary_new4
Definition: intern.h:92
static ID id_result
Definition: enumerator.c:108
static VALUE generator_init(VALUE obj, VALUE proc)
Definition: enumerator.c:1215
VALUE lookahead
Definition: enumerator.c:119
VALUE rb_eIndexError
Definition: error.c:550
static VALUE lazy_receiver_size(VALUE generator, VALUE args, VALUE lazy)
Definition: enumerator.c:1315
void rb_need_block(void)
Definition: eval.c:733
static VALUE yielder_yield_push(VALUE obj, VALUE args)
Definition: enumerator.c:1143
VALUE rb_int_succ(VALUE num)
Definition: numeric.c:2483
void rb_define_alias(VALUE klass, const char *name1, const char *name2)
Defines an alias of a method.
Definition: class.c:1688
#define enumerator_free
Definition: enumerator.c:156
VALUE rb_yield(VALUE)
Definition: vm_eval.c:948
static VALUE lazy_super(int argc, VALUE *argv, VALUE lazy)
Definition: enumerator.c:1927
#define RARRAY_CONST_PTR(a)
Definition: ruby.h:886
static ID id_yield
Definition: enumerator.c:107
VALUE rb_obj_is_proc(VALUE)
Definition: proc.c:94
static VALUE lazy_grep_func(RB_BLOCK_CALL_FUNC_ARGLIST(val, m))
Definition: enumerator.c:1659
VALUE rb_mEnumerable
Definition: enum.c:20
static VALUE lazy_drop_size(VALUE generator, VALUE args, VALUE lazy)
Definition: enumerator.c:1859
static VALUE lazy_take(VALUE obj, VALUE n)
Definition: enumerator.c:1819
VALUE rb_sprintf(const char *format,...)
Definition: sprintf.c:1250
#define const
Definition: strftime.c:102
VALUE rb_class_path(VALUE)
Definition: variable.c:257
static VALUE lazy_map_func(RB_BLOCK_CALL_FUNC_ARGLIST(val, m))
Definition: enumerator.c:1507
static VALUE enumerator_each_with_index(VALUE obj)
Definition: enumerator.c:554
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
Definition: class.c:1719
VALUE rb_ivar_set(VALUE, ID, VALUE)
Definition: variable.c:1133
#define PRIsVALUE
Definition: ruby.h:137
unsigned long ID
Definition: ruby.h:89
VALUE fib
Definition: enumerator.c:117
#define Qnil
Definition: ruby.h:427
VALUE rb_eStopIteration
Definition: enumerator.c:111
static ID id_eqq
Definition: enumerator.c:108
#define OBJ_TAINT(x)
Definition: ruby.h:1184
unsigned long VALUE
Definition: ruby.h:88
#define rb_funcall2
Definition: ruby.h:1464
static VALUE result
Definition: nkf.c:40
#define RETURN_SIZED_ENUMERATOR(obj, argc, argv, size_fn)
Definition: intern.h:237
static size_t enumerator_memsize(const void *p)
Definition: enumerator.c:159
VALUE rb_rescue2(VALUE(*b_proc)(ANYARGS), VALUE data1, VALUE(*r_proc)(ANYARGS), VALUE data2,...)
Definition: eval.c:741
#define rb_ary_new3
Definition: intern.h:91
VALUE stop_exc
Definition: enumerator.c:121
VALUE rb_check_funcall(VALUE, ID, int, const VALUE *)
Definition: vm_eval.c:410
VALUE rb_call_super(int, const VALUE *)
Definition: vm_eval.c:275
#define INFINITY
Definition: missing.h:141
VALUE rb_proc_call(VALUE, VALUE)
Definition: proc.c:744
static VALUE enumerator_initialize(int argc, VALUE *argv, VALUE obj)
Definition: enumerator.c:334
static VALUE lazy_select_func(RB_BLOCK_CALL_FUNC_ARGLIST(val, m))
Definition: enumerator.c:1613
#define RARRAY_LENINT(ary)
Definition: ruby.h:884
static VALUE lazy_reject_func(RB_BLOCK_CALL_FUNC_ARGLIST(val, m))
Definition: enumerator.c:1636
static VALUE generator_each(int argc, VALUE *argv, VALUE obj)
Definition: enumerator.c:1281
static VALUE lazy_lazy(VALUE obj)
Definition: enumerator.c:1933
static VALUE lazy_take_while_func(RB_BLOCK_CALL_FUNC_ARGLIST(val, args))
Definition: enumerator.c:1839
static VALUE lazy_initialize(int argc, VALUE *argv, VALUE self)
Definition: enumerator.c:1382
#define LONG2NUM(x)
Definition: ruby.h:1317
static VALUE lazy_grep_iter(RB_BLOCK_CALL_FUNC_ARGLIST(val, m))
Definition: enumerator.c:1671
int rb_respond_to(VALUE, ID)
Definition: vm_method.c:1651
VALUE rb_ary_new_from_values(long n, const VALUE *elts)
Definition: array.c:524
#define recur(fmt)
#define NEW_MEMO(a, b, c)
Definition: node.h:466
static ID id_receiver
Definition: enumerator.c:108
VALUE dst
Definition: enumerator.c:118
#define RFLOAT_VALUE(v)
Definition: ruby.h:814
int size
Definition: encoding.c:49
VALUE rb_yield_values2(int n, const VALUE *argv)
Definition: vm_eval.c:981
#define INT2FIX(i)
Definition: ruby.h:231
#define UNLIMITED_ARGUMENTS
Definition: intern.h:44
static VALUE sym_each
Definition: enumerator.c:109
VALUE rb_enum_values_pack(int argc, const VALUE *argv)
Definition: enum.c:33
static VALUE inspect_enumerator(VALUE obj, VALUE dummy, int recur)
Definition: enumerator.c:938
static struct generator * generator_ptr(VALUE obj)
Definition: enumerator.c:1190
#define RARRAY_AREF(a, i)
Definition: ruby.h:901
VALUE rb_block_proc(void)
Definition: proc.c:620
static VALUE next_stopped(VALUE obj)
Definition: enumerator.c:1699
VALUE rb_check_array_type(VALUE ary)
Definition: array.c:632
static VALUE enumerator_with_object_i(RB_BLOCK_CALL_FUNC_ARGLIST(val, memo))
Definition: enumerator.c:560
#define RARRAY_PTR(a)
Definition: ruby.h:907
static void yielder_mark(void *p)
Definition: enumerator.c:1059
#define LONG2FIX(i)
Definition: ruby.h:232
#define RTEST(v)
Definition: ruby.h:437
VALUE rb_proc_new(VALUE(*)(ANYARGS), VALUE)
Definition: proc.c:2312
#define OBJ_INFECT(x, s)
Definition: ruby.h:1188
static ID id_arguments
Definition: enumerator.c:108
static ID id_force
Definition: enumerator.c:108
void Init_Enumerator(void)
Definition: enumerator.c:2064
static ID id_size
Definition: enumerator.c:107
#define TypedData_Make_Struct(klass, type, data_type, sval)
Definition: ruby.h:1030
VALUE rb_ary_dup(VALUE ary)
Definition: array.c:1899
static VALUE enumerator_allocate(VALUE klass)
Definition: enumerator.c:258
static VALUE lazy_set_method(VALUE lazy, VALUE args, rb_enumerator_size_func *size_fn)
Definition: enumerator.c:1404
static VALUE enumerator_init_copy(VALUE obj, VALUE orig)
Definition: enumerator.c:368
static VALUE lazy_flat_map_to_ary(VALUE obj, VALUE yielder)
Definition: enumerator.c:1541
static const rb_data_type_t enumerator_data_type
Definition: enumerator.c:164
static ID id_call
Definition: enumerator.c:107
#define ID2SYM(x)
Definition: ruby.h:355
static VALUE yielder_initialize(VALUE obj)
Definition: enumerator.c:1126
static VALUE ary2sv(VALUE args, int dup)
Definition: enumerator.c:730
VALUE args
Definition: enumerator.c:116
VALUE rb_inspect(VALUE)
Definition: object.c:470
static ID id_new
Definition: enumerator.c:107
static VALUE enumerator_peek(VALUE obj)
Definition: enumerator.c:846
#define rb_check_frozen(obj)
Definition: intern.h:277
static size_t yielder_memsize(const void *p)
Definition: enumerator.c:1068
static VALUE lazy_drop_while(VALUE obj)
Definition: enumerator.c:1916
static VALUE enumerator_inspect(VALUE obj)
Definition: enumerator.c:1019
static ID id_rewind
Definition: enumerator.c:107
static VALUE lazy_zip(int argc, VALUE *argv, VALUE obj)
Definition: enumerator.c:1757
#define yielder_free
Definition: enumerator.c:1065
#define rb_intern(str)
static VALUE enumerator_with_index_i(RB_BLOCK_CALL_FUNC_ARGLIST(val, m))
Definition: enumerator.c:496
static VALUE lazy_drop_func(RB_BLOCK_CALL_FUNC_ARGLIST(val, args))
Definition: enumerator.c:1873
static VALUE yielder_yield_i(RB_BLOCK_CALL_FUNC_ARGLIST(obj, memo))
Definition: enumerator.c:1150
static VALUE enumerator_feed(VALUE obj, VALUE v)
Definition: enumerator.c:899
#define NULL
Definition: _sdbm.c:102
#define FIX2LONG(x)
Definition: ruby.h:345
#define Qundef
Definition: ruby.h:428
static VALUE rb_cYielder
Definition: enumerator.c:126
static struct yielder * yielder_ptr(VALUE obj)
Definition: enumerator.c:1084
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1479
VALUE rb_str_append(VALUE, VALUE)
Definition: string.c:2297
static ID id_each
Definition: enumerator.c:107
void rb_provide(const char *)
Definition: load.c:572
void rb_warn(const char *fmt,...)
Definition: error.c:223
ID rb_to_id(VALUE)
Definition: string.c:8734
VALUE rb_eArgError
Definition: error.c:549
static ID id_method
Definition: enumerator.c:108
static VALUE lazy_flat_map_each(VALUE obj, VALUE yielder)
Definition: enumerator.c:1534
#define NUM2LONG(x)
Definition: ruby.h:600
VALUE rb_attr_get(VALUE, ID)
Definition: variable.c:1127
char ** argv
Definition: ruby.c:132
VALUE rb_obj_class(VALUE)
Definition: object.c:226