[前][次][番号順一覧][スレッド一覧]

ruby-changes:22979

From: shugo <ko1@a...>
Date: Thu, 15 Mar 2012 11:00:44 +0900 (JST)
Subject: [ruby-changes:22979] shugo:r35028 (trunk): * enumerator.c (lazy_cycle): add Enumerable::Lazy#cycle.

shugo	2012-03-15 11:00:30 +0900 (Thu, 15 Mar 2012)

  New Revision: 35028

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=35028

  Log:
    * enumerator.c (lazy_cycle): add Enumerable::Lazy#cycle.

  Modified files:
    trunk/ChangeLog
    trunk/enumerator.c
    trunk/test/ruby/test_lazy_enumerator.rb

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 35027)
+++ ChangeLog	(revision 35028)
@@ -1,3 +1,7 @@
+Thu Mar 15 10:57:27 2012  Shugo Maeda  <shugo@r...>
+
+	* enumerator.c (lazy_cycle): add Enumerable::Lazy#cycle.
+
 Thu Mar 15 10:31:40 2012  Nobuyoshi Nakada  <nobu@r...>
 
 	* test/ruby/test_arity.rb (TestArity#err_mess): use assert_raise.
Index: enumerator.c
===================================================================
--- enumerator.c	(revision 35027)
+++ enumerator.c	(revision 35028)
@@ -1191,15 +1191,31 @@
 }
 
 static VALUE
-lazy_initialize(VALUE self, VALUE obj)
+lazy_initialize(int argc, VALUE *argv, VALUE self)
 {
+    VALUE obj, meth;
     VALUE generator;
+    int offset;
 
+    if (argc < 1) {
+	rb_raise(rb_eArgError, "wrong number of arguments (%d for 1..)", argc);
+    }
+    else {
+	obj = argv[0];
+	if (argc == 1) {
+	    meth = sym_each;
+	    offset = 1;
+	}
+	else {
+	    meth = argv[1];
+	    offset = 2;
+	}
+    }
     generator = generator_allocate(rb_cGenerator);
     rb_block_call(generator, id_initialize, 0, 0,
 		  (rb_block_given_p() ? lazy_init_block_i: lazy_init_block),
 		  obj);
-    enumerator_init(self, generator, sym_each, 0, 0);
+    enumerator_init(self, generator, meth, argc - offset, argv + offset);
 
     return self;
 }
@@ -1501,6 +1517,29 @@
 }
 
 static VALUE
+lazy_cycle_func(VALUE val, VALUE m, int argc, VALUE *argv)
+{
+    return rb_funcall2(argv[0], id_yield, argc - 1, argv + 1);
+}
+
+static VALUE
+lazy_cycle(int argc, VALUE *argv, VALUE obj)
+{
+    VALUE args;
+    int i;
+
+    args = rb_ary_new2(argc + 1);
+    rb_ary_push(args, obj);
+    rb_ary_push(args, ID2SYM(rb_intern("cycle")));
+    for (i = 0; i < argc; i++) {
+	rb_ary_push(args, argv[i]);
+    }
+    return rb_block_call(rb_cLazy, id_new, RARRAY_LEN(args), RARRAY_PTR(args),
+			 rb_block_given_p() ? lazy_map_func : lazy_cycle_func,
+			 0);
+}
+
+static VALUE
 lazy_lazy(VALUE obj)
 {
     return obj;
@@ -1587,7 +1626,7 @@
     /* Enumerable::Lazy */
     rb_cLazy = rb_define_class_under(rb_mEnumerable, "Lazy", rb_cEnumerator);
     rb_define_method(rb_mEnumerable, "lazy", enumerable_lazy, 0);
-    rb_define_method(rb_cLazy, "initialize", lazy_initialize, 1);
+    rb_define_method(rb_cLazy, "initialize", lazy_initialize, -1);
     rb_define_method(rb_cLazy, "map", lazy_map, 0);
     rb_define_method(rb_cLazy, "flat_map", lazy_flat_map, 0);
     rb_define_method(rb_cLazy, "select", lazy_select, 0);
@@ -1598,6 +1637,7 @@
     rb_define_method(rb_cLazy, "take_while", lazy_take_while, 0);
     rb_define_method(rb_cLazy, "drop", lazy_drop, 1);
     rb_define_method(rb_cLazy, "drop_while", lazy_drop_while, 0);
+    rb_define_method(rb_cLazy, "cycle", lazy_cycle, -1);
     rb_define_method(rb_cLazy, "lazy", lazy_lazy, 0);
 
     rb_define_alias(rb_cLazy, "collect", "map");
Index: test/ruby/test_lazy_enumerator.rb
===================================================================
--- test/ruby/test_lazy_enumerator.rb	(revision 35027)
+++ test/ruby/test_lazy_enumerator.rb	(revision 35028)
@@ -184,6 +184,16 @@
     assert_equal([4, 5], (1..Float::INFINITY).lazy.drop(3).take(2).to_a)
   end
 
+  def test_cycle
+    a = Step.new(1..3)
+    assert_equal("1", a.cycle(2).map(&:to_s).first)
+    assert_equal(3, a.current)
+    assert_equal("1", a.lazy.cycle(2).map(&:to_s).first)
+    assert_equal(1, a.current)
+    assert_equal("1", a.lazy.cycle(2, &:to_s).first)
+    assert_equal(1, a.current)
+  end
+
   def test_force
     assert_equal([1, 2, 3], (1..Float::INFINITY).lazy.take(3).force)
   end

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]