summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--array.c12
-rw-r--r--test/ruby/test_array.rb25
2 files changed, 33 insertions, 4 deletions
diff --git a/array.c b/array.c
index bc5c719267..3717c3ff34 100644
--- a/array.c
+++ b/array.c
@@ -4991,9 +4991,11 @@ rb_ary_uniq(VALUE ary)
{
VALUE hash, uniq;
- if (RARRAY_LEN(ary) <= 1)
- return rb_ary_dup(ary);
- if (rb_block_given_p()) {
+ if (RARRAY_LEN(ary) <= 1) {
+ hash = 0;
+ uniq = rb_ary_dup(ary);
+ }
+ else if (rb_block_given_p()) {
hash = ary_make_hash_by(ary);
uniq = rb_hash_values(hash);
}
@@ -5002,7 +5004,9 @@ rb_ary_uniq(VALUE ary)
uniq = rb_hash_values(hash);
}
RBASIC_SET_CLASS(uniq, rb_obj_class(ary));
- ary_recycle_hash(hash);
+ if (hash) {
+ ary_recycle_hash(hash);
+ }
return uniq;
}
diff --git a/test/ruby/test_array.rb b/test/ruby/test_array.rb
index 05f48abc8e..335c2dc042 100644
--- a/test/ruby/test_array.rb
+++ b/test/ruby/test_array.rb
@@ -1855,6 +1855,31 @@ class TestArray < Test::Unit::TestCase
ary = [bug9340, bug9340.dup, bug9340.dup]
assert_equal 1, ary.uniq.size
assert_same bug9340, ary.uniq[0]
+
+ sc = Class.new(@cls)
+ a = sc[]
+ b = a.dup
+ assert_instance_of(sc, a.uniq)
+ assert_equal(sc[], a.uniq)
+ assert_equal(b, a)
+
+ a = sc[1]
+ b = a.dup
+ assert_instance_of(sc, a.uniq)
+ assert_equal(sc[1], a.uniq)
+ assert_equal(b, a)
+
+ a = sc[1, 1]
+ b = a.dup
+ assert_instance_of(sc, a.uniq)
+ assert_equal(sc[1], a.uniq)
+ assert_equal(b, a)
+
+ a = sc[1, 1]
+ b = a.dup
+ assert_instance_of(sc, a.uniq{|x| x})
+ assert_equal(sc[1], a.uniq{|x| x})
+ assert_equal(b, a)
end
def test_uniq_with_block