diff options
| author | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2009-08-17 17:00:47 +0000 |
|---|---|---|
| committer | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2009-08-17 17:00:47 +0000 |
| commit | 6e2f7bbbc97175793bdb868ac1f9b9704a71611b (patch) | |
| tree | cd2950fed201e598e4c52fca8ba92ed67dde5f4d | |
| parent | 3ff18b0fdedc1291ca57195a6a3def98b7c5bbb2 (diff) | |
| download | ruby-6e2f7bbbc97175793bdb868ac1f9b9704a71611b.tar.gz ruby-6e2f7bbbc97175793bdb868ac1f9b9704a71611b.tar.xz ruby-6e2f7bbbc97175793bdb868ac1f9b9704a71611b.zip | |
* range.c (range_step): treat symbols specially so that iterating
over symbols should work like strings. [ruby-core:24780]
* range.c (range_each): ditto.
git-svn-id: http://svn.ruby-lang.org/repos/ruby/trunk@24573 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
| -rw-r--r-- | ChangeLog | 7 | ||||
| -rw-r--r-- | range.c | 41 | ||||
| -rw-r--r-- | test/ruby/test_range.rb | 4 |
3 files changed, 52 insertions, 0 deletions
@@ -1,3 +1,10 @@ +Tue Aug 18 01:57:00 2009 Yukihiro Matsumoto <matz@ruby-lang.org> + + * 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@ruby-lang.org> * range.c (range_each): should honor to_str conversion. @@ -261,6 +261,24 @@ range_each_func(VALUE range, VALUE (*func) (VALUE, void *), void *arg) } 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 @@ range_step(int argc, VALUE *argv, VALUE range) } } + 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 @@ each_i(VALUE v, void *arg) 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 @@ range_each(VALUE range) 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); diff --git a/test/ruby/test_range.rb b/test/ruby/test_range.rb index 94e6583d2..69eba8845 100644 --- a/test/ruby/test_range.rb +++ b/test/ruby/test_range.rb @@ -18,6 +18,10 @@ class TestRange < Test::Unit::TestCase 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) |
