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

ruby-changes:12841

From: matz <ko1@a...>
Date: Tue, 18 Aug 2009 02:01:13 +0900 (JST)
Subject: [ruby-changes:12841] Ruby:r24573 (trunk): * range.c (range_step): treat symbols specially so that iterating

matz	2009-08-18 02:00:47 +0900 (Tue, 18 Aug 2009)

  New Revision: 24573

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

  Log:
    * range.c (range_step): treat symbols specially so that iterating
      over symbols should work like strings.  [ruby-core:24780]
    * range.c (range_each): ditto.

  Modified files:
    trunk/ChangeLog
    trunk/range.c
    trunk/test/ruby/test_range.rb

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 24572)
+++ ChangeLog	(revision 24573)
@@ -1,3 +1,10 @@
+Tue Aug 18 01:57:00 2009  Yukihiro Matsumoto  <matz@r...>
+
+	* range.c (range_step): treat symbols specially so that iterating
+	  over symbols should work like strings.  [ruby-core:24780]
+
+	* range.c (range_each): ditto.
+
 Tue Aug 18 01:21:31 2009  Yukihiro Matsumoto  <matz@r...>
 
 	* range.c (range_each): should honor to_str conversion.
Index: range.c
===================================================================
--- range.c	(revision 24572)
+++ range.c	(revision 24573)
@@ -261,6 +261,24 @@
 }
 
 static VALUE
+sym_step_i(VALUE i, void *arg)
+{
+    VALUE *iter = arg;
+
+    if (FIXNUM_P(iter[0])) {
+	iter[0] -= INT2FIX(1) & ~FIXNUM_FLAG;
+    }
+    else {
+	iter[0] = rb_funcall(iter[0], '-', 1, INT2FIX(1));
+    }
+    if (iter[0] == INT2FIX(0)) {
+	rb_yield(rb_str_intern(i));
+	iter[0] = iter[1];
+    }
+    return Qnil;
+}
+
+static VALUE
 step_i(VALUE i, void *arg)
 {
     VALUE *iter = arg;
@@ -347,6 +365,15 @@
 	}
 
     }
+    else if (SYMBOL_P(b) && SYMBOL_P(e)) { /* symbols are special */
+	VALUE args[2], iter[2];
+
+	args[0] = rb_sym_to_s(e);
+	args[1] = EXCL(range) ? Qtrue : Qfalse;
+	iter[0] = INT2FIX(1);
+	iter[1] = step;
+	rb_block_call(rb_sym_to_s(b), rb_intern("upto"), 2, args, sym_step_i, (VALUE)iter);
+    }
     else if (ruby_float_step(b, e, step, EXCL(range))) {
 	/* done */
     }
@@ -398,6 +425,13 @@
     return Qnil;
 }
 
+static VALUE
+sym_each_i(VALUE v, void *arg)
+{
+    rb_yield(rb_str_intern(v));
+    return Qnil;
+}
+
 /*
  *  call-seq:
  *     rng.each {| i | block } => rng
@@ -436,6 +470,13 @@
 	    rb_yield(LONG2FIX(i));
 	}
     }
+    else if (SYMBOL_P(beg) && SYMBOL_P(end)) { /* symbols are special */
+	VALUE args[2];
+
+	args[0] = rb_sym_to_s(end);
+	args[1] = EXCL(range) ? Qtrue : Qfalse;
+	rb_block_call(rb_sym_to_s(beg), rb_intern("upto"), 2, args, sym_each_i, 0);
+    }
     else {
 	VALUE tmp = rb_check_string_type(beg);
 
Index: test/ruby/test_range.rb
===================================================================
--- test/ruby/test_range.rb	(revision 24572)
+++ test/ruby/test_range.rb	(revision 24573)
@@ -18,6 +18,10 @@
     assert_equal(["9", "10"], ("9"..SimpleDelegator.new("10")).to_a)
   end
 
+  def test_range_symbol
+    assert_equal([:a, :b], (:a .. :b).to_a)
+  end
+
   def test_evaluation_order
     arr = [1,2]
     r = (arr.shift)..(arr.shift)

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

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