Feature #14084 ยป enumerator_next.diff
enumerator.c | ||
---|---|---|
return ary2sv(vs, 0);
|
||
}
|
||
/*
|
||
* call-seq:
|
||
* e.next? -> object
|
||
*
|
||
* Returns whether there is a next object in the enumerator, but doesn't
|
||
* move the internal position forward.
|
||
*
|
||
* === Example
|
||
*
|
||
* a = [1,2,3]
|
||
* e = a.to_enum
|
||
* p e.next? #=> true
|
||
* p e.next #=> 1
|
||
* p e.next? #=> true
|
||
* p e.next #=> 2
|
||
* p e.next? #=> true
|
||
* p e.next #=> 3
|
||
* p e.next? #=> false
|
||
* p e.next #raises StopIteration
|
||
*
|
||
*/
|
||
static VALUE
|
||
enumerator_has_next(VALUE obj)
|
||
{
|
||
struct enumerator *e = enumerator_ptr(obj);
|
||
if (e->stop_exc)
|
||
return Qfalse;
|
||
if (e->lookahead != Qundef)
|
||
return Qtrue;
|
||
VALUE curr, vs;
|
||
curr = rb_fiber_current();
|
||
if (!e->fib || !rb_fiber_alive_p(e->fib)) {
|
||
next_init(obj, e);
|
||
}
|
||
vs = rb_fiber_resume(e->fib, 1, &curr);
|
||
if (e->stop_exc) {
|
||
e->fib = 0;
|
||
e->dst = Qnil;
|
||
e->lookahead = Qundef;
|
||
e->feedvalue = Qundef;
|
||
return Qfalse;
|
||
}
|
||
e->lookahead = vs;
|
||
return Qtrue;
|
||
}
|
||
static VALUE
|
||
enumerator_peek_values(VALUE obj)
|
||
{
|
||
... | ... | |
rb_define_method(rb_cEnumerator, "next_values", enumerator_next_values, 0);
|
||
rb_define_method(rb_cEnumerator, "peek_values", enumerator_peek_values_m, 0);
|
||
rb_define_method(rb_cEnumerator, "next", enumerator_next, 0);
|
||
rb_define_method(rb_cEnumerator, "next?", enumerator_has_next, 0);
|
||
rb_define_method(rb_cEnumerator, "peek", enumerator_peek, 0);
|
||
rb_define_method(rb_cEnumerator, "feed", enumerator_feed, 1);
|
||
rb_define_method(rb_cEnumerator, "rewind", enumerator_rewind, 0);
|
test/ruby/test_enumerator.rb | ||
---|---|---|
assert_raise(StopIteration){e.next}
|
||
end
|
||
def test_next?
|
||
e = 3.times
|
||
3.times{|i|
|
||
assert_equal true, e.next?
|
||
e.next
|
||
}
|
||
assert_equal false, e.next?
|
||
end
|
||
def test_loop
|
||
e = 3.times
|
||
i = 0
|