[前][次][番号順一覧][スレッド一覧]

ruby-changes:57503

From: Jeremy <ko1@a...>
Date: Tue, 3 Sep 2019 07:09:24 +0900 (JST)
Subject: [ruby-changes:57503] 1994adf938 (master): Make Array#uniq return subclass instance if called on subclass instance

https://git.ruby-lang.org/ruby.git/commit/?id=1994adf938

From 1994adf938afcdc562f87497156e6d4900f3f06b Mon Sep 17 00:00:00 2001
From: Jeremy Evans <code@j...>
Date: Mon, 15 Jul 2019 14:03:28 -0700
Subject: 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]

diff --git a/array.c b/array.c
index bc5c719..3717c3f 100644
--- a/array.c
+++ b/array.c
@@ -4991,9 +4991,11 @@ rb_ary_uniq(VALUE ary) https://github.com/ruby/ruby/blob/trunk/array.c#L4991
 {
     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) https://github.com/ruby/ruby/blob/trunk/array.c#L5004
 	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 05f48ab..335c2dc 100644
--- a/test/ruby/test_array.rb
+++ b/test/ruby/test_array.rb
@@ -1855,6 +1855,31 @@ class TestArray < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_array.rb#L1855
     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
-- 
cgit v0.10.2


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]