aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--enumerator.c19
-rw-r--r--test/ruby/test_lazy_enumerator.rb6
3 files changed, 25 insertions, 5 deletions
diff --git a/ChangeLog b/ChangeLog
index 7395dfc127..f677791c3a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+Fri Mar 16 11:20:07 2012 Shugo Maeda <shugo@ruby-lang.org>
+
+ * enumerator.c (lazy_take): don't enumerate an extra value.
+ [ruby-dev:45370] [Bug #6152]
+
Fri Mar 16 06:30:10 2012 Nobuyoshi Nakada <nobu@ruby-lang.org>
* enumerator.c (lazy_zip_func): variadic argument needs explicit cast
diff --git a/enumerator.c b/enumerator.c
index c473260479..0edf2177fa 100644
--- a/enumerator.c
+++ b/enumerator.c
@@ -1449,10 +1449,13 @@ lazy_take_func(VALUE val, VALUE args, int argc, VALUE *argv)
{
NODE *memo = RNODE(args);
- if (memo->u3.cnt == 0) return Qundef;
rb_funcall2(argv[0], id_yield, argc - 1, argv + 1);
- memo->u3.cnt--;
- return Qnil;
+ if (--memo->u3.cnt == 0) {
+ return Qundef;
+ }
+ else {
+ return Qnil;
+ }
}
static VALUE
@@ -1460,12 +1463,20 @@ lazy_take(VALUE obj, VALUE n)
{
NODE *memo;
long len = NUM2LONG(n);
+ int argc = 1;
+ VALUE argv[3];
if (len < 0) {
rb_raise(rb_eArgError, "attempt to take negative size");
}
+ argv[0] = obj;
+ if (len == 0) {
+ argv[1] = sym_cycle;
+ argv[2] = INT2NUM(0);
+ argc = 3;
+ }
memo = NEW_MEMO(0, 0, len);
- return rb_block_call(rb_cLazy, id_new, 1, &obj, lazy_take_func,
+ return rb_block_call(rb_cLazy, id_new, argc, argv, lazy_take_func,
(VALUE) memo);
}
diff --git a/test/ruby/test_lazy_enumerator.rb b/test/ruby/test_lazy_enumerator.rb
index b096821191..0f2fa2bc41 100644
--- a/test/ruby/test_lazy_enumerator.rb
+++ b/test/ruby/test_lazy_enumerator.rb
@@ -201,7 +201,11 @@ class TestLazyEnumerator < Test::Unit::TestCase
assert_equal(5, a.current)
assert_equal(1, a.lazy.take(5).first)
assert_equal(1, a.current)
- assert_equal((1..5).to_a, a.lazy.take(5).to_a)
+ assert_equal((1..5).to_a, a.lazy.take(5).force)
+ assert_equal(5, a.current)
+ a = Step.new(1..10)
+ assert_equal([], a.lazy.take(0).force)
+ assert_equal(nil, a.current)
end
def test_take_while