1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

Make Array#uniq return subclass instance if called on subclass instance

Previously, Array#uniq would return subclass instance if the
length of the array were 2 or greater, and would return Array
instance if the length of the array were 0 or 1.

Fixes [Bug #7768]
This commit is contained in:
Jeremy Evans 2019-07-15 14:03:28 -07:00
parent a848b62819
commit 1994adf938
2 changed files with 33 additions and 4 deletions

12
array.c
View file

@ -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;
}

View file

@ -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