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