A class which provides a method `each' to be used as an Enumerable object.
Creates a new Enumerator object, which is to be used as an Enumerable object iterating in a given way.
In the first form, a generated Enumerator iterates over the given object using the given method with the given arguments passed. Use of this form is discouraged. Use Kernel#enum_for(), alias to_enum, instead.
e = Enumerator.new(ObjectSpace, :each_object) #-> ObjectSpace.enum_for(:each_object) e.select { |obj| obj.is_a?(Class) } #=> array of all classes
In the second form, iteration is defined by the given block, in which a
“yielder” object given as block parameter can be used to yield a value by
calling the yield
method, alias +<<+.
fib = Enumerator.new { |y| a = b = 1 loop { y << a a, b = b, a + b } } p fib.take(10) #=> [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
static VALUE enumerator_initialize(int argc, VALUE *argv, VALUE obj) { VALUE recv, meth = sym_each; if (argc == 0) { if (!rb_block_given_p()) rb_raise(rb_eArgError, "wrong number of argument (0 for 1+)"); recv = generator_init(generator_allocate(rb_cGenerator), rb_block_proc()); } else { recv = *argv++; if (--argc) { meth = *argv++; --argc; } } return enumerator_init(obj, recv, meth, argc, argv); }
Iterates the given block using the object and the method specified in the first place. If no block is given, returns self.
static VALUE enumerator_each(VALUE obj) { struct enumerator *e; int argc = 0; VALUE *argv = 0; if (!rb_block_given_p()) return obj; e = enumerator_ptr(obj); if (e->args) { argc = RARRAY_LEN(e->args); argv = RARRAY_PTR(e->args); } return rb_block_call(e->obj, e->meth, argc, argv, enumerator_each_i, (VALUE)e); }
Iterates the given block for each element with an index, which start from 0. If no block is given, returns an enumerator.
static VALUE enumerator_with_index(VALUE obj) { struct enumerator *e; VALUE memo = 0; int argc = 0; VALUE *argv = 0; RETURN_ENUMERATOR(obj, 0, 0); e = enumerator_ptr(obj); if (e->args) { argc = RARRAY_LEN(e->args); argv = RARRAY_PTR(e->args); } return rb_block_call(e->obj, e->meth, argc, argv, enumerator_with_index_i, (VALUE)&memo); }
Iterates the given block for each element with an arbitrary object given, and returns the initially given object.
If no block is given, returns an enumerator.
static VALUE enumerator_with_object(VALUE obj, VALUE memo) { struct enumerator *e; int argc = 0; VALUE *argv = 0; RETURN_ENUMERATOR(obj, 1, &memo); e = enumerator_ptr(obj); if (e->args) { argc = RARRAY_LEN(e->args); argv = RARRAY_PTR(e->args); } rb_block_call(e->obj, e->meth, argc, argv, enumerator_with_object_i, memo); return memo; }
Returns the next object in the enumerator, and move the internal position forward. When the position reached at the end, internal position is rewound then StopIteration is raised.
Note that enumeration sequence by next method does not affect other non-external enumeration methods, unless underlying iteration methods itself has side-effect, e.g. IO#each_line.
static VALUE enumerator_next(VALUE obj) { struct enumerator *e = enumerator_ptr(obj); VALUE curr, v; curr = rb_fiber_current(); if (!e->fib || !rb_fiber_alive_p(e->fib)) { next_init(obj, e); } v = rb_fiber_resume(e->fib, 1, &curr); if (e->no_next) { e->fib = 0; e->dst = Qnil; e->no_next = Qfalse; rb_raise(rb_eStopIteration, "iteration reached at end"); } return v; }
Rewinds the enumeration sequence by the next method.
If the enclosed object responds to a “rewind” method, it is called.
static VALUE enumerator_rewind(VALUE obj) { struct enumerator *e = enumerator_ptr(obj); if (rb_respond_to(e->obj, id_rewind)) rb_funcall(e->obj, id_rewind, 0); e->fib = 0; e->dst = Qnil; e->no_next = Qfalse; return obj; }
Iterates the given block for each element with an index, which start from 0. If no block is given, returns an enumerator.
static VALUE enumerator_with_index(VALUE obj) { struct enumerator *e; VALUE memo = 0; int argc = 0; VALUE *argv = 0; RETURN_ENUMERATOR(obj, 0, 0); e = enumerator_ptr(obj); if (e->args) { argc = RARRAY_LEN(e->args); argv = RARRAY_PTR(e->args); } return rb_block_call(e->obj, e->meth, argc, argv, enumerator_with_index_i, (VALUE)&memo); }
Iterates the given block for each element with an arbitrary object given, and returns the initially given object.
If no block is given, returns an enumerator.
static VALUE enumerator_with_object(VALUE obj, VALUE memo) { struct enumerator *e; int argc = 0; VALUE *argv = 0; RETURN_ENUMERATOR(obj, 1, &memo); e = enumerator_ptr(obj); if (e->args) { argc = RARRAY_LEN(e->args); argv = RARRAY_PTR(e->args); } rb_block_call(e->obj, e->meth, argc, argv, enumerator_with_object_i, memo); return memo; }