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/