summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--enumerator.c15
-rw-r--r--test/ruby/test_lazy_enumerator.rb6
3 files changed, 25 insertions, 1 deletions
diff --git a/ChangeLog b/ChangeLog
index 5231b8c026..9d088f46ed 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+Thu Mar 15 19:12:31 2012 Shugo Maeda <shugo@ruby-lang.org>
+
+ * enumerator.c (lazy_zip): rescue StopIteration returned by
+ Enumerator#next.
+
Thu Mar 15 18:19:53 2012 Shugo Maeda <shugo@ruby-lang.org>
* enumerator.c (lazy_zip, lazy_cycle): Enumerator::Lazy#{zip,cycle}
diff --git a/enumerator.c b/enumerator.c
index ea4d4fcbe4..09543940f4 100644
--- a/enumerator.c
+++ b/enumerator.c
@@ -1374,6 +1374,18 @@ lazy_grep(VALUE obj, VALUE pattern)
}
static VALUE
+call_next(VALUE obj)
+{
+ return rb_funcall(obj, id_next, 0);
+}
+
+static VALUE
+next_stopped(VALUE obj)
+{
+ return Qnil;
+}
+
+static VALUE
lazy_zip_func(VALUE val, VALUE arg, int argc, VALUE *argv)
{
VALUE yielder, ary, v;
@@ -1383,7 +1395,8 @@ lazy_zip_func(VALUE val, VALUE arg, int argc, VALUE *argv)
ary = rb_ary_new2(RARRAY_LEN(arg) + 1);
rb_ary_push(ary, argv[1]);
for (i = 0; i < RARRAY_LEN(arg); i++) {
- v = rb_funcall(RARRAY_PTR(arg)[i], id_next, 0);
+ v = rb_rescue2(call_next, RARRAY_PTR(arg)[i], next_stopped, 0,
+ rb_eStopIteration, 0);
rb_ary_push(ary, v);
}
rb_funcall(yielder, id_yield, 1, ary);
diff --git a/test/ruby/test_lazy_enumerator.rb b/test/ruby/test_lazy_enumerator.rb
index f6fc870fb6..7064f3b178 100644
--- a/test/ruby/test_lazy_enumerator.rb
+++ b/test/ruby/test_lazy_enumerator.rb
@@ -130,6 +130,12 @@ class TestLazyEnumerator < Test::Unit::TestCase
assert_equal(1, a.current)
end
+ def test_zip_short_arg
+ a = Step.new(1..5)
+ assert_equal([5, nil], a.zip("a".."c").last)
+ assert_equal([5, nil], a.lazy.zip("a".."c").force.last)
+ end
+
def test_zip_without_arg
a = Step.new(1..3)
assert_equal([1], a.zip.first)