summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog15
-rw-r--r--array.c13
-rw-r--r--test/ruby/test_array.rb38
3 files changed, 60 insertions, 6 deletions
diff --git a/ChangeLog b/ChangeLog
index 53c084d1bb..b656eed538 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+Tue Dec 3 13:40:42 2013 Masaki Matsushita <glass.saga@gmail.com>
+
+ * array.c (ary_add_hash): set and return values because string keys
+ will be frozen. [ruby-core:58809] [Bug #9202]
+
+ * array.c (rb_ary_uniq_bang): ditto.
+
+ * array.c (rb_ary_or): ditto.
+
+ * array.c (rb_ary_uniq): ditto.
+
+ * test/ruby/test_array.rb: tests for above.
+
+ The patch is from normalperson (Eric Wong).
+
Tue Dec 3 12:20:21 2013 Aman Gupta <ruby@tmm1.net>
* string.c (rb_fstring): Use st_update instead of st_lookup +
diff --git a/array.c b/array.c
index 1a6af6e70a..8a71e2c8b7 100644
--- a/array.c
+++ b/array.c
@@ -3905,7 +3905,8 @@ ary_add_hash(VALUE hash, VALUE ary)
long i;
for (i=0; i<RARRAY_LEN(ary); i++) {
- rb_hash_aset(hash, RARRAY_AREF(ary, i), Qtrue);
+ VALUE elt = RARRAY_AREF(ary, i);
+ rb_hash_aset(hash, elt, elt);
}
return hash;
}
@@ -4056,15 +4057,15 @@ rb_ary_or(VALUE ary1, VALUE ary2)
ary2 = to_ary(ary2);
hash = ary_add_hash(ary_make_hash(ary1), ary2);
- ary3 = rb_hash_keys(hash);
+ ary3 = rb_hash_values(hash);
ary_recycle_hash(hash);
return ary3;
}
static int
-push_key(st_data_t key, st_data_t val, st_data_t ary)
+push_val(st_data_t key, st_data_t val, st_data_t ary)
{
- rb_ary_push((VALUE)ary, (VALUE)key);
+ rb_ary_push((VALUE)ary, (VALUE)val);
return ST_CONTINUE;
}
@@ -4137,7 +4138,7 @@ rb_ary_uniq_bang(VALUE ary)
FL_SET_EMBED(ary);
}
ary_resize_capa(ary, hash_size);
- st_foreach(rb_hash_tbl_raw(hash), push_key, ary);
+ st_foreach(rb_hash_tbl_raw(hash), push_val, ary);
}
ary_recycle_hash(hash);
@@ -4176,7 +4177,7 @@ rb_ary_uniq(VALUE ary)
}
else {
hash = ary_make_hash(ary);
- uniq = rb_hash_keys(hash);
+ uniq = rb_hash_values(hash);
}
RBASIC_SET_CLASS(uniq, rb_obj_class(ary));
ary_recycle_hash(hash);
diff --git a/test/ruby/test_array.rb b/test/ruby/test_array.rb
index 9411c6a088..45013df412 100644
--- a/test/ruby/test_array.rb
+++ b/test/ruby/test_array.rb
@@ -1507,6 +1507,13 @@ class TestArray < Test::Unit::TestCase
assert_equal(d, c)
assert_equal(@cls[1, 2, 3], @cls[1, 2, 3].uniq)
+
+ a = %w(a a)
+ b = a.uniq
+ assert_equal(%w(a a), a)
+ assert(a.none?(&:frozen?))
+ assert_equal(%w(a), b)
+ assert(b.none?(&:frozen?))
end
def test_uniq_with_block
@@ -1527,6 +1534,13 @@ class TestArray < Test::Unit::TestCase
assert_equal([1,3], a)
assert_equal([1], b)
assert_not_same(a, b)
+
+ a = %w(a a)
+ b = a.uniq {|v| v }
+ assert_equal(%w(a a), a)
+ assert(a.none?(&:frozen?))
+ assert_equal(%w(a), b)
+ assert(b.none?(&:frozen?))
end
def test_uniq!
@@ -1573,6 +1587,13 @@ class TestArray < Test::Unit::TestCase
a.sort_by!{|e| e[:c]}
a.uniq! {|e| e[:c]}
end
+
+ a = %w(a a)
+ b = a.uniq
+ assert_equal(%w(a a), a)
+ assert(a.none?(&:frozen?))
+ assert_equal(%w(a), b)
+ assert(b.none?(&:frozen?))
end
def test_uniq_bang_with_block
@@ -1594,6 +1615,12 @@ class TestArray < Test::Unit::TestCase
b = a.uniq! {|v| v.even? }
assert_equal([1,2], a)
assert_equal(nil, b)
+
+ a = %w(a a)
+ b = a.uniq! {|v| v }
+ assert_equal(%w(a), b)
+ assert_same(a, b)
+ assert b.none?(&:frozen?)
end
def test_uniq_bang_with_freeze
@@ -1622,6 +1649,17 @@ class TestArray < Test::Unit::TestCase
assert_equal(@cls[1,2], @cls[1] | @cls[2])
assert_equal(@cls[1,2], @cls[1, 1] | @cls[2, 2])
assert_equal(@cls[1,2], @cls[1, 2] | @cls[1, 2])
+
+ a = %w(a b c)
+ b = %w(a b c d e)
+ c = a | b
+ assert_equal(c, b)
+ assert_not_same(c, b)
+ assert_equal(%w(a b c), a)
+ assert_equal(%w(a b c d e), b)
+ assert(a.none?(&:frozen?))
+ assert(b.none?(&:frozen?))
+ assert(c.none?(&:frozen?))
end
def test_combination