summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog6
-rw-r--r--string.c9
-rw-r--r--test/ruby/test_string.rb11
3 files changed, 23 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog
index efc2edf0a8..37a6335d45 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+Wed Nov 4 00:05:36 2009 NARUSE, Yui <naruse@ruby-lang.org>
+
+ * string.c (rb_str_upto): make next object before yield its block.
+ fix: can modify original begin string of String#upto.
+ [ruby-dev:26384] [ruby-dev:39626]
+
Mon Nov 2 18:33:21 2009 wanabe <s.wanabe@gmail.com>
* cont.c (fiber_free): don't free unallocated local_storage. see #1325.
diff --git a/string.c b/string.c
index e7f7e8673a..f67997939d 100644
--- a/string.c
+++ b/string.c
@@ -2952,11 +2952,14 @@ rb_str_upto(int argc, VALUE *argv, VALUE beg)
if (n > 0 || (excl && n == 0)) return beg;
after_end = rb_funcall(end, succ, 0, 0);
- current = beg;
+ current = rb_str_dup(beg);
while (!rb_str_equal(current, after_end)) {
+ VALUE next = Qnil;
+ if (excl || !rb_str_equal(current, end))
+ next = rb_funcall(current, succ, 0, 0);
rb_yield(current);
- if (!excl && rb_str_equal(current, end)) break;
- current = rb_funcall(current, succ, 0, 0);
+ if (NIL_P(next)) break;
+ current = next;
StringValue(current);
if (excl && rb_str_equal(current, end)) break;
if (RSTRING_LEN(current) > RSTRING_LEN(end) || RSTRING_LEN(current) == 0)
diff --git a/test/ruby/test_string.rb b/test/ruby/test_string.rb
index 290f53634d..27360e76c1 100644
--- a/test/ruby/test_string.rb
+++ b/test/ruby/test_string.rb
@@ -1602,6 +1602,17 @@ class TestString < Test::Unit::TestCase
assert_equal(24, count, "[ruby-dev:39361]")
end
+ def test_upto_nonalnum
+ first = S("\u3041")
+ last = S("\u3093")
+ count = 0
+ assert_equal(first, first.upto(last) {|s|
+ count += 1
+ s.replace(last)
+ })
+ assert_equal(83, count, "[ruby-dev:39626]")
+ end
+
def test_mod_check
assert_raise(RuntimeError) {
s = ""