Ruby  1.9.3p448(2013-06-27revision41675)
enumerator.c
Go to the documentation of this file.
1 /************************************************
2 
3  enumerator.c - provides Enumerator class
4 
5  $Author: marcandre $
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 34713 2012-02-20 23:55:19Z marcandre $
12 
13 ************************************************/
14 
15 #include "ruby/ruby.h"
16 
17 /*
18  * Document-class: Enumerator
19  *
20  * A class which allows both internal and external iteration.
21  *
22  * An Enumerator can be created by the following methods.
23  * - Kernel#to_enum
24  * - Kernel#enum_for
25  * - Enumerator.new
26  *
27  * Most methods have two forms: a block form where the contents
28  * are evaluated for each item in the enumeration, and a non-block form
29  * which returns a new Enumerator wrapping the iteration.
30  *
31  * enumerator = %w(one two three).each
32  * puts enumerator.class # => Enumerator
33  * enumerator.each_with_object("foo") do |item,obj|
34  * puts "#{obj}: #{item}"
35  * end
36  * # foo: one
37  * # foo: two
38  * # foo: three
39  * enum_with_obj = enumerator.each_with_object("foo")
40  * puts enum_with_obj.class # => Enumerator
41  * enum_with_obj.each do |item,obj|
42  * puts "#{obj: #{item}"
43  * end
44  * # foo: one
45  * # foo: two
46  * # foo: three
47  *
48  * This allows you to chain Enumerators together. For example, you
49  * can map a list's elements to strings containing the index
50  * and the element as a string via:
51  *
52  * puts %w[foo bar baz].map.with_index {|w,i| "#{i}:#{w}" }
53  * # => ["0:foo", "1:bar", "2:baz"]
54  *
55  * An Enumerator can also be used as an external iterator.
56  * For example, Enumerator#next returns the next value of the iterator
57  * or raises StopIteration if the Enumerator is at the end.
58  *
59  * e = [1,2,3].each # returns an enumerator object.
60  * puts e.next # => 1
61  * puts e.next # => 2
62  * puts e.next # => 3
63  * puts e.next # raises StopIteration
64  *
65  * You can use this to implement an internal iterator as follows:
66  *
67  * def ext_each(e)
68  * while true
69  * begin
70  * vs = e.next_values
71  * rescue StopIteration
72  * return $!.result
73  * end
74  * y = yield(*vs)
75  * e.feed y
76  * end
77  * end
78  *
79  * o = Object.new
80  *
81  * def o.each
82  * puts yield
83  * puts yield(1)
84  * puts yield(1, 2)
85  * 3
86  * end
87  *
88  * # use o.each as an internal iterator directly.
89  * puts o.each {|*x| puts x; [:b, *x] }
90  * # => [], [:b], [1], [:b, 1], [1, 2], [:b, 1, 2], 3
91  *
92  * # convert o.each to an external iterator for
93  * # implementing an internal iterator.
94  * puts ext_each(o.to_enum) {|*x| puts x; [:b, *x] }
95  * # => [], [:b], [1], [:b, 1], [1, 2], [:b, 1, 2], 3
96  *
97  */
101 
103 
104 struct enumerator {
113 };
114 
116 
117 struct generator {
119 };
120 
121 struct yielder {
123 };
124 
125 static VALUE generator_allocate(VALUE klass);
126 static VALUE generator_init(VALUE obj, VALUE proc);
127 
128 /*
129  * Enumerator
130  */
131 static void
133 {
134  struct enumerator *ptr = p;
135  rb_gc_mark(ptr->obj);
136  rb_gc_mark(ptr->args);
137  rb_gc_mark(ptr->fib);
138  rb_gc_mark(ptr->dst);
139  rb_gc_mark(ptr->lookahead);
140  rb_gc_mark(ptr->feedvalue);
141  rb_gc_mark(ptr->stop_exc);
142 }
143 
144 #define enumerator_free RUBY_TYPED_DEFAULT_FREE
145 
146 static size_t
147 enumerator_memsize(const void *p)
148 {
149  return p ? sizeof(struct enumerator) : 0;
150 }
151 
153  "enumerator",
154  {
158  },
159 };
160 
161 static struct enumerator *
163 {
164  struct enumerator *ptr;
165 
167  if (!ptr || ptr->obj == Qundef) {
168  rb_raise(rb_eArgError, "uninitialized enumerator");
169  }
170  return ptr;
171 }
172 
173 /*
174  * call-seq:
175  * obj.to_enum(method = :each, *args)
176  * obj.enum_for(method = :each, *args)
177  *
178  * Creates a new Enumerator which will enumerate by on calling +method+ on
179  * +obj+.
180  *
181  * +method+:: the method to call on +obj+ to generate the enumeration
182  * +args+:: arguments that will be passed in +method+ <i>in addition</i>
183  * to the item itself. Note that the number of args
184  * must not exceed the number expected by +method+
185  *
186  * === Example
187  *
188  * str = "xyz"
189  *
190  * enum = str.enum_for(:each_byte)
191  * enum.each { |b| puts b }
192  * # => 120
193  * # => 121
194  * # => 122
195  *
196  * # protect an array from being modified by some_method
197  * a = [1, 2, 3]
198  * some_method(a.to_enum)
199  *
200  */
201 static VALUE
203 {
204  VALUE meth = sym_each;
205 
206  if (argc > 0) {
207  --argc;
208  meth = *argv++;
209  }
210  return rb_enumeratorize(obj, meth, argc, argv);
211 }
212 
213 static VALUE
215 {
216  struct enumerator *ptr;
217  VALUE enum_obj;
218 
219  enum_obj = TypedData_Make_Struct(klass, struct enumerator, &enumerator_data_type, ptr);
220  ptr->obj = Qundef;
221 
222  return enum_obj;
223 }
224 
225 static VALUE
227 {
228  struct enumerator *ptr;
229 
230  TypedData_Get_Struct(enum_obj, struct enumerator, &enumerator_data_type, ptr);
231 
232  if (!ptr) {
233  rb_raise(rb_eArgError, "unallocated enumerator");
234  }
235 
236  ptr->obj = obj;
237  ptr->meth = rb_to_id(meth);
238  if (argc) ptr->args = rb_ary_new4(argc, argv);
239  ptr->fib = 0;
240  ptr->dst = Qnil;
241  ptr->lookahead = Qundef;
242  ptr->feedvalue = Qundef;
243  ptr->stop_exc = Qfalse;
244 
245  return enum_obj;
246 }
247 
248 /*
249  * call-seq:
250  * Enumerator.new { |yielder| ... }
251  * Enumerator.new(obj, method = :each, *args)
252  *
253  * Creates a new Enumerator object, which can be used as an
254  * Enumerable.
255  *
256  * In the first form, iteration is defined by the given block, in
257  * which a "yielder" object, given as block parameter, can be used to
258  * yield a value by calling the +yield+ method (aliased as +<<+):
259  *
260  * fib = Enumerator.new do |y|
261  * a = b = 1
262  * loop do
263  * y << a
264  * a, b = b, a + b
265  * end
266  * end
267  *
268  * p fib.take(10) # => [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
269  *
270  * In the second, deprecated, form, a generated Enumerator iterates over the
271  * given object using the given method with the given arguments passed.
272  *
273  * Use of this form is discouraged. Use Kernel#enum_for or Kernel#to_enum
274  * instead.
275  *
276  * e = Enumerator.new(ObjectSpace, :each_object)
277  * #-> ObjectSpace.enum_for(:each_object)
278  *
279  * e.select { |obj| obj.is_a?(Class) } #=> array of all classes
280  *
281  */
282 static VALUE
284 {
285  VALUE recv, meth = sym_each;
286 
287  if (argc == 0) {
288  if (!rb_block_given_p())
289  rb_raise(rb_eArgError, "wrong number of argument (0 for 1+)");
290 
292  }
293  else {
294  recv = *argv++;
295  if (--argc) {
296  meth = *argv++;
297  --argc;
298  }
299  }
300 
301  return enumerator_init(obj, recv, meth, argc, argv);
302 }
303 
304 /* :nodoc: */
305 static VALUE
307 {
308  struct enumerator *ptr0, *ptr1;
309 
310  ptr0 = enumerator_ptr(orig);
311  if (ptr0->fib) {
312  /* Fibers cannot be copied */
313  rb_raise(rb_eTypeError, "can't copy execution context");
314  }
315 
317 
318  if (!ptr1) {
319  rb_raise(rb_eArgError, "unallocated enumerator");
320  }
321 
322  ptr1->obj = ptr0->obj;
323  ptr1->meth = ptr0->meth;
324  ptr1->args = ptr0->args;
325  ptr1->fib = 0;
326  ptr1->lookahead = Qundef;
327  ptr1->feedvalue = Qundef;
328 
329  return obj;
330 }
331 
332 VALUE
334 {
335  return enumerator_init(enumerator_allocate(rb_cEnumerator), obj, meth, argc, argv);
336 }
337 
338 static VALUE
340 {
341  int argc = 0;
342  VALUE *argv = 0;
343  const struct enumerator *e = enumerator_ptr(obj);
344  ID meth = e->meth;
345 
346  if (e->args) {
347  argc = RARRAY_LENINT(e->args);
348  argv = RARRAY_PTR(e->args);
349  }
350  return rb_block_call(e->obj, meth, argc, argv, func, arg);
351 }
352 
353 /*
354  * call-seq:
355  * enum.each {...}
356  *
357  * Iterates over the block according to how this Enumerable was constructed.
358  * If no block is given, returns self.
359  *
360  */
361 static VALUE
363 {
364  if (!rb_block_given_p()) return obj;
365  return enumerator_block_call(obj, 0, obj);
366 }
367 
368 static VALUE
370 {
371  VALUE idx;
372  VALUE *memo = (VALUE *)m;
373 
374  idx = INT2FIX(*memo);
375  ++*memo;
376 
377  if (argc <= 1)
378  return rb_yield_values(2, val, idx);
379 
380  return rb_yield_values(2, rb_ary_new4(argc, argv), idx);
381 }
382 
383 /*
384  * call-seq:
385  * e.with_index(offset = 0) {|(*args), idx| ... }
386  * e.with_index(offset = 0)
387  *
388  * Iterates the given block for each element with an index, which
389  * starts from +offset+. If no block is given, returns a new Enumerator
390  * that includes the index, starting from +offset+
391  *
392  * +offset+:: the starting index to use
393  *
394  */
395 static VALUE
397 {
398  VALUE memo;
399 
400  rb_scan_args(argc, argv, "01", &memo);
401  RETURN_ENUMERATOR(obj, argc, argv);
402  memo = NIL_P(memo) ? 0 : (VALUE)NUM2LONG(memo);
404 }
405 
406 /*
407  * call-seq:
408  * e.each_with_index {|(*args), idx| ... }
409  * e.each_with_index
410  *
411  * Same as Enumerator#with_index(0), i.e. there is no starting offset.
412  *
413  * If no block is given, a new Enumerator is returned that includes the index.
414  *
415  */
416 static VALUE
418 {
419  return enumerator_with_index(0, NULL, obj);
420 }
421 
422 static VALUE
424 {
425  if (argc <= 1)
426  return rb_yield_values(2, val, memo);
427 
428  return rb_yield_values(2, rb_ary_new4(argc, argv), memo);
429 }
430 
431 /*
432  * call-seq:
433  * e.with_object(obj) {|(*args), obj| ... }
434  * e.with_object(obj)
435  *
436  * Iterates the given block for each element with an arbitrary object, +obj+,
437  * and returns +obj+
438  *
439  * If no block is given, returns a new Enumerator.
440  *
441  * === Example
442  *
443  * to_three = Enumerator.new do |y|
444  * 3.times do |x|
445  * y << x
446  * end
447  * end
448  *
449  * to_three_with_string = to_three.with_object("foo")
450  * to_three_with_string.each do |x,string|
451  * puts "#{string}: #{x}"
452  * end
453  *
454  * # => foo:0
455  * # => foo:1
456  * # => foo:2
457  */
458 static VALUE
460 {
461  RETURN_ENUMERATOR(obj, 1, &memo);
463 
464  return memo;
465 }
466 
467 static VALUE
469 {
470  struct enumerator *e = enumerator_ptr(obj);
471  VALUE feedvalue = Qnil;
472  VALUE args = rb_ary_new4(argc, argv);
473  rb_fiber_yield(1, &args);
474  if (e->feedvalue != Qundef) {
475  feedvalue = e->feedvalue;
476  e->feedvalue = Qundef;
477  }
478  return feedvalue;
479 }
480 
481 static VALUE
483 {
484  struct enumerator *e = enumerator_ptr(obj);
485  VALUE nil = Qnil;
486  VALUE result;
487 
488  result = rb_block_call(obj, id_each, 0, 0, next_ii, obj);
489  e->stop_exc = rb_exc_new2(rb_eStopIteration, "iteration reached an end");
490  rb_ivar_set(e->stop_exc, rb_intern("result"), result);
491  return rb_fiber_yield(1, &nil);
492 }
493 
494 static void
496 {
497  VALUE curr = rb_fiber_current();
498  e->dst = curr;
499  e->fib = rb_fiber_new(next_i, obj);
500  e->lookahead = Qundef;
501 }
502 
503 static VALUE
505 {
506  VALUE curr, vs;
507 
508  if (e->stop_exc)
510 
511  curr = rb_fiber_current();
512 
513  if (!e->fib || !rb_fiber_alive_p(e->fib)) {
514  next_init(obj, e);
515  }
516 
517  vs = rb_fiber_resume(e->fib, 1, &curr);
518  if (e->stop_exc) {
519  e->fib = 0;
520  e->dst = Qnil;
521  e->lookahead = Qundef;
522  e->feedvalue = Qundef;
524  }
525  return vs;
526 }
527 
528 /*
529  * call-seq:
530  * e.next_values -> array
531  *
532  * Returns the next object as an array in the enumerator, and move the
533  * internal position forward. When the position reached at the end,
534  * StopIteration is raised.
535  *
536  * This method can be used to distinguish <code>yield</code> and <code>yield
537  * nil</code>.
538  *
539  * === Example
540  *
541  * o = Object.new
542  * def o.each
543  * yield
544  * yield 1
545  * yield 1, 2
546  * yield nil
547  * yield [1, 2]
548  * end
549  * e = o.to_enum
550  * p e.next_values
551  * p e.next_values
552  * p e.next_values
553  * p e.next_values
554  * p e.next_values
555  * e = o.to_enum
556  * p e.next
557  * p e.next
558  * p e.next
559  * p e.next
560  * p e.next
561  *
562  * ## yield args next_values next
563  * # yield [] nil
564  * # yield 1 [1] 1
565  * # yield 1, 2 [1, 2] [1, 2]
566  * # yield nil [nil] nil
567  * # yield [1, 2] [[1, 2]] [1, 2]
568  *
569  * Note that +next_values+ does not affect other non-external enumeration
570  * methods unless underlying iteration method itself has side-effect, e.g.
571  * IO#each_line.
572  *
573  */
574 
575 static VALUE
577 {
578  struct enumerator *e = enumerator_ptr(obj);
579  VALUE vs;
580 
581  if (e->lookahead != Qundef) {
582  vs = e->lookahead;
583  e->lookahead = Qundef;
584  return vs;
585  }
586 
587  return get_next_values(obj, e);
588 }
589 
590 static VALUE
591 ary2sv(VALUE args, int dup)
592 {
593  if (TYPE(args) != T_ARRAY)
594  return args;
595 
596  switch (RARRAY_LEN(args)) {
597  case 0:
598  return Qnil;
599 
600  case 1:
601  return RARRAY_PTR(args)[0];
602 
603  default:
604  if (dup)
605  return rb_ary_dup(args);
606  return args;
607  }
608 }
609 
610 /*
611  * call-seq:
612  * e.next -> object
613  *
614  * Returns the next object in the enumerator, and move the internal position
615  * forward. When the position reached at the end, StopIteration is raised.
616  *
617  * === Example
618  *
619  * a = [1,2,3]
620  * e = a.to_enum
621  * p e.next #=> 1
622  * p e.next #=> 2
623  * p e.next #=> 3
624  * p e.next #raises StopIteration
625  *
626  * Note that enumeration sequence by +next+ does not affect other non-external
627  * enumeration methods, unless the underlying iteration methods itself has
628  * side-effect, e.g. IO#each_line.
629  *
630  */
631 
632 static VALUE
634 {
635  VALUE vs = enumerator_next_values(obj);
636  return ary2sv(vs, 0);
637 }
638 
639 static VALUE
641 {
642  struct enumerator *e = enumerator_ptr(obj);
643 
644  if (e->lookahead == Qundef) {
645  e->lookahead = get_next_values(obj, e);
646  }
647  return e->lookahead;
648 }
649 
650 /*
651  * call-seq:
652  * e.peek_values -> array
653  *
654  * Returns the next object as an array, similar to Enumerator#next_values, but
655  * doesn't move the internal position forward. If the position is already at
656  * the end, StopIteration is raised.
657  *
658  * === Example
659  *
660  * o = Object.new
661  * def o.each
662  * yield
663  * yield 1
664  * yield 1, 2
665  * end
666  * e = o.to_enum
667  * p e.peek_values #=> []
668  * e.next
669  * p e.peek_values #=> [1]
670  * p e.peek_values #=> [1]
671  * e.next
672  * p e.peek_values #=> [1, 2]
673  * e.next
674  * p e.peek_values # raises StopIteration
675  *
676  */
677 
678 static VALUE
680 {
681  return rb_ary_dup(enumerator_peek_values(obj));
682 }
683 
684 /*
685  * call-seq:
686  * e.peek -> object
687  *
688  * Returns the next object in the enumerator, but doesn't move the internal
689  * position forward. If the position is already at the end, StopIteration
690  * is raised.
691  *
692  * === Example
693  *
694  * a = [1,2,3]
695  * e = a.to_enum
696  * p e.next #=> 1
697  * p e.peek #=> 2
698  * p e.peek #=> 2
699  * p e.peek #=> 2
700  * p e.next #=> 2
701  * p e.next #=> 3
702  * p e.next #raises StopIteration
703  *
704  */
705 
706 static VALUE
708 {
709  VALUE vs = enumerator_peek_values(obj);
710  return ary2sv(vs, 1);
711 }
712 
713 /*
714  * call-seq:
715  * e.feed obj -> nil
716  *
717  * Sets the value to be returned by the next yield inside +e+.
718  *
719  * If the value is not set, the yield returns nil.
720  *
721  * This value is cleared after being yielded.
722  *
723  * o = Object.new
724  * def o.each
725  * x = yield # (2) blocks
726  * p x # (5) => "foo"
727  * x = yield # (6) blocks
728  * p x # (8) => nil
729  * x = yield # (9) blocks
730  * p x # not reached w/o another e.next
731  * end
732  *
733  * e = o.to_enum
734  * e.next # (1)
735  * e.feed "foo" # (3)
736  * e.next # (4)
737  * e.next # (7)
738  * # (10)
739  */
740 
741 static VALUE
743 {
744  struct enumerator *e = enumerator_ptr(obj);
745 
746  if (e->feedvalue != Qundef) {
747  rb_raise(rb_eTypeError, "feed value already set");
748  }
749  e->feedvalue = v;
750 
751  return Qnil;
752 }
753 
754 /*
755  * call-seq:
756  * e.rewind -> e
757  *
758  * Rewinds the enumeration sequence to the beginning.
759  *
760  * If the enclosed object responds to a "rewind" method, it is called.
761  */
762 
763 static VALUE
765 {
766  struct enumerator *e = enumerator_ptr(obj);
767 
768  rb_check_funcall(e->obj, id_rewind, 0, 0);
769 
770  e->fib = 0;
771  e->dst = Qnil;
772  e->lookahead = Qundef;
773  e->feedvalue = Qundef;
774  e->stop_exc = Qfalse;
775  return obj;
776 }
777 
778 static VALUE
780 {
781  struct enumerator *e;
782  const char *cname;
783  VALUE eobj, str;
784  int tainted, untrusted;
785 
787 
788  cname = rb_obj_classname(obj);
789 
790  if (!e || e->obj == Qundef) {
791  return rb_sprintf("#<%s: uninitialized>", cname);
792  }
793 
794  if (recur) {
795  str = rb_sprintf("#<%s: ...>", cname);
796  OBJ_TAINT(str);
797  return str;
798  }
799 
800  eobj = e->obj;
801 
802  tainted = OBJ_TAINTED(eobj);
803  untrusted = OBJ_UNTRUSTED(eobj);
804 
805  /* (1..100).each_cons(2) => "#<Enumerator: 1..100:each_cons(2)>" */
806  str = rb_sprintf("#<%s: ", cname);
807  rb_str_concat(str, rb_inspect(eobj));
808  rb_str_buf_cat2(str, ":");
809  rb_str_buf_cat2(str, rb_id2name(e->meth));
810 
811  if (e->args) {
812  long argc = RARRAY_LEN(e->args);
813  VALUE *argv = RARRAY_PTR(e->args);
814 
815  rb_str_buf_cat2(str, "(");
816 
817  while (argc--) {
818  VALUE arg = *argv++;
819 
820  rb_str_concat(str, rb_inspect(arg));
821  rb_str_buf_cat2(str, argc > 0 ? ", " : ")");
822 
823  if (OBJ_TAINTED(arg)) tainted = TRUE;
824  if (OBJ_UNTRUSTED(arg)) untrusted = TRUE;
825  }
826  }
827 
828  rb_str_buf_cat2(str, ">");
829 
830  if (tainted) OBJ_TAINT(str);
831  if (untrusted) OBJ_UNTRUST(str);
832  return str;
833 }
834 
835 /*
836  * call-seq:
837  * e.inspect -> string
838  *
839  * Creates a printable version of <i>e</i>.
840  */
841 
842 static VALUE
844 {
845  return rb_exec_recursive(inspect_enumerator, obj, 0);
846 }
847 
848 /*
849  * Yielder
850  */
851 static void
852 yielder_mark(void *p)
853 {
854  struct yielder *ptr = p;
855  rb_gc_mark(ptr->proc);
856 }
857 
858 #define yielder_free RUBY_TYPED_DEFAULT_FREE
859 
860 static size_t
861 yielder_memsize(const void *p)
862 {
863  return p ? sizeof(struct yielder) : 0;
864 }
865 
867  "yielder",
868  {
869  yielder_mark,
870  yielder_free,
872  },
873 };
874 
875 static struct yielder *
877 {
878  struct yielder *ptr;
879 
880  TypedData_Get_Struct(obj, struct yielder, &yielder_data_type, ptr);
881  if (!ptr || ptr->proc == Qundef) {
882  rb_raise(rb_eArgError, "uninitialized yielder");
883  }
884  return ptr;
885 }
886 
887 /* :nodoc: */
888 static VALUE
890 {
891  struct yielder *ptr;
892  VALUE obj;
893 
894  obj = TypedData_Make_Struct(klass, struct yielder, &yielder_data_type, ptr);
895  ptr->proc = Qundef;
896 
897  return obj;
898 }
899 
900 static VALUE
902 {
903  struct yielder *ptr;
904 
905  TypedData_Get_Struct(obj, struct yielder, &yielder_data_type, ptr);
906 
907  if (!ptr) {
908  rb_raise(rb_eArgError, "unallocated yielder");
909  }
910 
911  ptr->proc = proc;
912 
913  return obj;
914 }
915 
916 /* :nodoc: */
917 static VALUE
919 {
920  rb_need_block();
921 
922  return yielder_init(obj, rb_block_proc());
923 }
924 
925 /* :nodoc: */
926 static VALUE
928 {
929  struct yielder *ptr = yielder_ptr(obj);
930 
931  return rb_proc_call(ptr->proc, args);
932 }
933 
934 /* :nodoc: */
936 {
937  yielder_yield(obj, args);
938  return obj;
939 }
940 
941 static VALUE
943 {
944  return rb_yield_values2(argc, argv);
945 }
946 
947 static VALUE
949 {
951 }
952 
953 /*
954  * Generator
955  */
956 static void
958 {
959  struct generator *ptr = p;
960  rb_gc_mark(ptr->proc);
961 }
962 
963 #define generator_free RUBY_TYPED_DEFAULT_FREE
964 
965 static size_t
966 generator_memsize(const void *p)
967 {
968  return p ? sizeof(struct generator) : 0;
969 }
970 
972  "generator",
973  {
977  },
978 };
979 
980 static struct generator *
982 {
983  struct generator *ptr;
984 
986  if (!ptr || ptr->proc == Qundef) {
987  rb_raise(rb_eArgError, "uninitialized generator");
988  }
989  return ptr;
990 }
991 
992 /* :nodoc: */
993 static VALUE
995 {
996  struct generator *ptr;
997  VALUE obj;
998 
999  obj = TypedData_Make_Struct(klass, struct generator, &generator_data_type, ptr);
1000  ptr->proc = Qundef;
1001 
1002  return obj;
1003 }
1004 
1005 static VALUE
1007 {
1008  struct generator *ptr;
1009 
1011 
1012  if (!ptr) {
1013  rb_raise(rb_eArgError, "unallocated generator");
1014  }
1015 
1016  ptr->proc = proc;
1017 
1018  return obj;
1019 }
1020 
1021 /* :nodoc: */
1022 static VALUE
1024 {
1025  VALUE proc;
1026 
1027  if (argc == 0) {
1028  rb_need_block();
1029 
1030  proc = rb_block_proc();
1031  } else {
1032  rb_scan_args(argc, argv, "1", &proc);
1033 
1034  if (!rb_obj_is_proc(proc))
1036  "wrong argument type %s (expected Proc)",
1037  rb_obj_classname(proc));
1038 
1039  if (rb_block_given_p()) {
1040  rb_warn("given block not used");
1041  }
1042  }
1043 
1044  return generator_init(obj, proc);
1045 }
1046 
1047 /* :nodoc: */
1048 static VALUE
1050 {
1051  struct generator *ptr0, *ptr1;
1052 
1053  ptr0 = generator_ptr(orig);
1054 
1055  TypedData_Get_Struct(obj, struct generator, &generator_data_type, ptr1);
1056 
1057  if (!ptr1) {
1058  rb_raise(rb_eArgError, "unallocated generator");
1059  }
1060 
1061  ptr1->proc = ptr0->proc;
1062 
1063  return obj;
1064 }
1065 
1066 /* :nodoc: */
1067 static VALUE
1069 {
1070  struct generator *ptr = generator_ptr(obj);
1071  VALUE yielder;
1072 
1073  yielder = yielder_new();
1074 
1075  return rb_proc_call(ptr->proc, rb_ary_new3(1, yielder));
1076 }
1077 
1078 /*
1079  * Document-class: StopIteration
1080  *
1081  * Raised to stop the iteration, in particular by Enumerator#next. It is
1082  * rescued by Kernel#loop.
1083  *
1084  * loop do
1085  * puts "Hello"
1086  * raise StopIteration
1087  * puts "World"
1088  * end
1089  * puts "Done!"
1090  *
1091  * <em>produces:</em>
1092  *
1093  * Hello
1094  * Done!
1095  */
1096 
1097 /*
1098  * call-seq:
1099  * result -> value
1100  *
1101  * Returns the return value of the iterator.
1102  *
1103  * o = Object.new
1104  * def o.each
1105  * yield 1
1106  * yield 2
1107  * yield 3
1108  * 100
1109  * end
1110  *
1111  * e = o.to_enum
1112  *
1113  * puts e.next #=> 1
1114  * puts e.next #=> 2
1115  * puts e.next #=> 3
1116  *
1117  * begin
1118  * e.next
1119  * rescue StopIteration => ex
1120  * puts ex.result #=> 100
1121  * end
1122  *
1123  */
1124 static VALUE
1126 {
1127  return rb_attr_get(self, rb_intern("result"));
1128 }
1129 
1130 void
1132 {
1133  rb_define_method(rb_mKernel, "to_enum", obj_to_enum, -1);
1134  rb_define_method(rb_mKernel, "enum_for", obj_to_enum, -1);
1135 
1136  rb_cEnumerator = rb_define_class("Enumerator", rb_cObject);
1138 
1141  rb_define_method(rb_cEnumerator, "initialize_copy", enumerator_init_copy, 1);
1144  rb_define_method(rb_cEnumerator, "each_with_object", enumerator_with_object, 1);
1154 
1155  rb_eStopIteration = rb_define_class("StopIteration", rb_eIndexError);
1157 
1158  /* Generator */
1163  rb_define_method(rb_cGenerator, "initialize_copy", generator_init_copy, 1);
1165 
1166  /* Yielder */
1169  rb_define_method(rb_cYielder, "initialize", yielder_initialize, 0);
1172 
1173  id_rewind = rb_intern("rewind");
1174  id_each = rb_intern("each");
1175  sym_each = ID2SYM(id_each);
1176 
1177  rb_provide("enumerator.so"); /* for backward compatibility */
1178 }
static long NUM2LONG(VALUE x)
Definition: ruby.h:510
static void enumerator_mark(void *p)
Definition: enumerator.c:132
VALUE rb_ary_new4(long n, const VALUE *elts)
Definition: array.c:366
static VALUE next_i(VALUE curr, VALUE obj)
Definition: enumerator.c:482
static VALUE rb_cGenerator
Definition: enumerator.c:115
static VALUE enumerator_rewind(VALUE obj)
Definition: enumerator.c:764
int i
Definition: win32ole.c:776
VALUE rb_yield_values(int n,...)
Definition: vm_eval.c:792
static void generator_mark(void *p)
Definition: enumerator.c:957
static VALUE enumerator_peek_values(VALUE obj)
Definition: enumerator.c:640
static VALUE yielder_new(void)
Definition: enumerator.c:948
static VALUE generator_init_copy(VALUE obj, VALUE orig)
Definition: enumerator.c:1049
static size_t generator_memsize(const void *p)
Definition: enumerator.c:966
VALUE feedvalue
Definition: enumerator.c:111
static VALUE yielder_allocate(VALUE klass)
Definition: enumerator.c:889
static VALUE enumerator_each(VALUE obj)
Definition: enumerator.c:362
#define rb_block_call(arg1, arg2, arg3, arg4, arg5, arg6)
Definition: ruby_missing.h:38
#define TypedData_Get_Struct(obj, type, data_type, sval)
Definition: ruby.h:840
static VALUE yielder_init(VALUE obj, VALUE proc)
Definition: enumerator.c:901
VALUE rb_eTypeError
Definition: error.c:467
static VALUE enumerator_with_object_i(VALUE val, VALUE memo, int argc, VALUE *argv)
Definition: enumerator.c:423
VALUE rb_str_concat(VALUE, VALUE)
Definition: string.c:2080
VALUE rb_fiber_yield(int argc, VALUE *argv)
Definition: cont.c:1351
static const rb_data_type_t generator_data_type
Definition: enumerator.c:971
static VALUE enumerator_next_values(VALUE obj)
Definition: enumerator.c:576
VALUE rb_cEnumerator
Definition: enumerator.c:98
VALUE rb_fiber_alive_p(VALUE fibval)
Definition: cont.c:1379
VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super)
Defines a class under the namespace of outer.
Definition: class.c:514
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:1574
VALUE obj
Definition: enumerator.c:105
VALUE rb_fiber_current(void)
Definition: cont.c:1201
static const rb_data_type_t yielder_data_type
Definition: enumerator.c:866
VALUE rb_exec_recursive(VALUE(*)(VALUE, VALUE, int), VALUE, VALUE)
Definition: thread.c:4037
void rb_define_alloc_func(VALUE, rb_alloc_func_t)
VALUE proc
Definition: enumerator.c:118
#define generator_free
Definition: enumerator.c:963
#define RARRAY_LEN(ARRAY)
Definition: generator.h:39
VALUE rb_ary_new3(long n,...)
Definition: array.c:347
static VALUE enumerator_next(VALUE obj)
Definition: enumerator.c:633
void rb_include_module(VALUE klass, VALUE module)
Definition: class.c:662
static VALUE enumerator_block_call(VALUE obj, rb_block_call_func *func, VALUE arg)
Definition: enumerator.c:339
void rb_gc_mark(VALUE ptr)
Definition: gc.c:1762
#define T_ARRAY
Definition: ruby.h:420
static VALUE yielder_yield(VALUE obj, VALUE args)
Definition: enumerator.c:927
#define ID2SYM(i)
Definition: cparse.c:63
static VALUE generator_initialize(int argc, VALUE *argv, VALUE obj)
Definition: enumerator.c:1023
static VALUE generator_allocate(VALUE klass)
Definition: enumerator.c:994
static VALUE yielder_yield_i(VALUE obj, VALUE memo, int argc, VALUE *argv)
Definition: enumerator.c:942
#define OBJ_TAINTED(x)
Definition: ruby.h:963
const char * rb_obj_classname(VALUE)
Definition: variable.c:318
static VALUE enumerator_with_object(VALUE obj, VALUE memo)
Definition: enumerator.c:459
Win32OLEIDispatch * p
Definition: win32ole.c:778
static VALUE generator_each(VALUE obj)
Definition: enumerator.c:1068
VALUE rb_enumeratorize(VALUE obj, VALUE meth, int argc, VALUE *argv)
Definition: enumerator.c:333
void rb_exc_raise(VALUE mesg)
Definition: eval.c:460
static struct enumerator * enumerator_ptr(VALUE obj)
Definition: enumerator.c:162
int args
Definition: win32ole.c:777
static VALUE get_next_values(VALUE obj, struct enumerator *e)
Definition: enumerator.c:504
VALUE rb_fiber_resume(VALUE fibval, int argc, VALUE *argv)
Definition: cont.c:1338
static VALUE enumerator_with_index(int argc, VALUE *argv, VALUE obj)
Definition: enumerator.c:396
int rb_block_given_p(void)
Definition: eval.c:604
static VALUE obj_to_enum(int argc, VALUE *argv, VALUE obj)
Definition: enumerator.c:202
RUBY_EXTERN VALUE rb_cObject
Definition: ruby.h:1246
VALUE rb_str_buf_cat2(VALUE, const char *)
Definition: string.c:1875
RUBY_EXTERN VALUE rb_mKernel
Definition: ruby.h:1234
static VALUE enumerator_peek_values_m(VALUE obj)
Definition: enumerator.c:679
#define NIL_P(v)
Definition: ruby.h:374
VALUE rb_define_class(const char *name, VALUE super)
Defines a top-level class.
Definition: class.c:468
static void next_init(VALUE obj, struct enumerator *e)
Definition: enumerator.c:495
VALUE proc
Definition: enumerator.c:122
VALUE rb_fiber_new(VALUE(*func)(ANYARGS), VALUE obj)
Definition: cont.c:1091
static VALUE stop_result(VALUE self)
Definition: enumerator.c:1125
#define OBJ_UNTRUST(x)
Definition: ruby.h:966
#define TYPE(x)
Definition: ruby.h:441
int argc
Definition: ruby.c:120
#define Qfalse
Definition: ruby.h:365
static VALUE enumerator_with_index_i(VALUE val, VALUE m, int argc, VALUE *argv)
Definition: enumerator.c:369
arg
Definition: ripper.y:1283
static VALUE generator_init(VALUE obj, VALUE proc)
Definition: enumerator.c:1006
VALUE lookahead
Definition: enumerator.c:110
VALUE rb_eIndexError
Definition: error.c:469
void rb_need_block(void)
Definition: eval.c:626
static VALUE yielder_yield_push(VALUE obj, VALUE args)
Definition: enumerator.c:935
#define enumerator_free
Definition: enumerator.c:144
SSL_METHOD *(* func)(void)
Definition: ossl_ssl.c:104
#define TRUE
Definition: nkf.h:186
VALUE rb_obj_is_proc(VALUE)
Definition: proc.c:88
VALUE rb_check_funcall(VALUE, ID, int, VALUE *)
Definition: vm_eval.c:312
#define OBJ_UNTRUSTED(x)
Definition: ruby.h:965
VALUE rb_mEnumerable
Definition: enum.c:17
VALUE rb_sprintf(const char *format,...)
Definition: sprintf.c:1203
#define const
Definition: strftime.c:101
static VALUE enumerator_each_with_index(VALUE obj)
Definition: enumerator.c:417
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
Definition: class.c:1415
VALUE rb_ivar_set(VALUE, ID, VALUE)
Definition: variable.c:1038
unsigned long ID
Definition: ruby.h:89
#define NULL
VALUE fib
Definition: enumerator.c:108
#define Qnil
Definition: ruby.h:367
VALUE rb_exc_new2(VALUE etype, const char *s)
Definition: error.c:498
VALUE rb_eStopIteration
Definition: enumerator.c:102
#define OBJ_TAINT(x)
Definition: ruby.h:964
unsigned long VALUE
Definition: ruby.h:88
static VALUE result
Definition: nkf.c:40
static size_t enumerator_memsize(const void *p)
Definition: enumerator.c:147
VALUE stop_exc
Definition: enumerator.c:112
#define RARRAY_PTR(ARRAY)
Definition: generator.h:36
VALUE rb_proc_call(VALUE, VALUE)
Definition: proc.c:574
static VALUE enumerator_initialize(int argc, VALUE *argv, VALUE obj)
Definition: enumerator.c:283
VALUE rb_block_call_func(VALUE, VALUE, int, VALUE *)
Definition: ruby.h:1198
#define RARRAY_LENINT(ary)
Definition: ruby.h:718
#define recur(fmt)
VALUE dst
Definition: enumerator.c:109
VALUE rb_yield_values2(int n, const VALUE *argv)
Definition: vm_eval.c:814
#define INT2FIX(i)
Definition: ruby.h:225
static VALUE sym_each
Definition: enumerator.c:100
static VALUE inspect_enumerator(VALUE obj, VALUE dummy, int recur)
Definition: enumerator.c:779
static struct generator * generator_ptr(VALUE obj)
Definition: enumerator.c:981
VALUE rb_block_proc(void)
Definition: proc.c:463
static void yielder_mark(void *p)
Definition: enumerator.c:852
VALUE rb_proc_new(VALUE(*)(ANYARGS), VALUE)
Definition: proc.c:1837
v
Definition: win32ole.c:790
void Init_Enumerator(void)
Definition: enumerator.c:1131
static VALUE next_ii(VALUE i, VALUE obj, int argc, VALUE *argv)
Definition: enumerator.c:468
#define TypedData_Make_Struct(klass, type, data_type, sval)
Definition: ruby.h:829
VALUE rb_ary_dup(VALUE ary)
Definition: array.c:1597
static VALUE enumerator_allocate(VALUE klass)
Definition: enumerator.c:214
static VALUE enumerator_init_copy(VALUE obj, VALUE orig)
Definition: enumerator.c:306
#define RETURN_ENUMERATOR(obj, argc, argv)
Definition: intern.h:210
static const rb_data_type_t enumerator_data_type
Definition: enumerator.c:152
static VALUE enumerator_init(VALUE enum_obj, VALUE obj, VALUE meth, int argc, VALUE *argv)
Definition: enumerator.c:226
static VALUE yielder_initialize(VALUE obj)
Definition: enumerator.c:918
const char * rb_id2name(ID id)
Definition: ripper.c:15493
static VALUE ary2sv(VALUE args, int dup)
Definition: enumerator.c:591
VALUE args
Definition: enumerator.c:107
VALUE rb_inspect(VALUE)
Definition: object.c:372
static VALUE enumerator_peek(VALUE obj)
Definition: enumerator.c:707
static size_t yielder_memsize(const void *p)
Definition: enumerator.c:861
static VALUE enumerator_inspect(VALUE obj)
Definition: enumerator.c:843
static ID id_rewind
Definition: enumerator.c:99
#define yielder_free
Definition: enumerator.c:858
#define rb_intern(str)
static VALUE enumerator_feed(VALUE obj, VALUE v)
Definition: enumerator.c:742
#define Qundef
Definition: ruby.h:368
static VALUE rb_cYielder
Definition: enumerator.c:115
static struct yielder * yielder_ptr(VALUE obj)
Definition: enumerator.c:876
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1209
static ID id_each
Definition: enumerator.c:99
void rb_provide(const char *)
Definition: load.c:265
void rb_warn(const char *fmt,...)
Definition: error.c:196
ID rb_to_id(VALUE)
Definition: string.c:7732
VALUE rb_eArgError
Definition: error.c:468
VALUE rb_attr_get(VALUE, ID)
Definition: variable.c:1032
char ** argv
Definition: ruby.c:121