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

ruby-changes:63512

From: Jeremy <ko1@a...>
Date: Wed, 4 Nov 2020 07:02:00 +0900 (JST)
Subject: [ruby-changes:63512] 2a294d499b (master): Make Array methods return Array instances instead of subclass instances

https://git.ruby-lang.org/ruby.git/commit/?id=2a294d499b

From 2a294d499bf03211d02695f613f784a05943ea35 Mon Sep 17 00:00:00 2001
From: Jeremy Evans <code@j...>
Date: Tue, 3 Nov 2020 14:01:38 -0800
Subject: Make Array methods return Array instances instead of subclass
 instances

This changes the following methods to return Array instances instead
of subclass instances:

* Array#drop
* Array#drop_while
* Array#flatten
* Array#slice!
* Array#slice/#[]
* Array#take
* Array#take_while
* Array#uniq
* Array#*

Fixes [Bug #6087]

diff --git a/array.c b/array.c
index 6cd6412..8cb9f51 100644
--- a/array.c
+++ b/array.c
@@ -1189,7 +1189,7 @@ ary_make_partial_step(VALUE ary, VALUE klass, long offset, long len, long step) https://github.com/ruby/ruby/blob/trunk/array.c#L1189
 static VALUE
 ary_make_shared_copy(VALUE ary)
 {
-    return ary_make_partial(ary, rb_obj_class(ary), 0, RARRAY_LEN(ary));
+    return ary_make_partial(ary, rb_cArray, 0, RARRAY_LEN(ary));
 }
 
 enum ary_take_pos_flags
@@ -1628,7 +1628,7 @@ rb_ary_subseq_step(VALUE ary, long beg, long len, long step) https://github.com/ruby/ruby/blob/trunk/array.c#L1628
     if (alen < len || alen < beg + len) {
 	len = alen - beg;
     }
-    klass = rb_obj_class(ary);
+    klass = rb_cArray;
     if (len == 0) return ary_new(klass, 0);
     if (step == 0)
         rb_raise(rb_eArgError, "slice step cannot be zero");
@@ -4010,7 +4010,6 @@ ary_slice_bang_by_rb_ary_splice(VALUE ary, long pos, long len) https://github.com/ruby/ruby/blob/trunk/array.c#L4010
     }
     else {
         VALUE arg2 = rb_ary_new4(len, RARRAY_CONST_PTR_TRANSIENT(ary)+pos);
-        RBASIC_SET_CLASS(arg2, rb_obj_class(ary));
         rb_ary_splice(ary, pos, len, 0, 0);
         return arg2;
     }
@@ -4820,7 +4819,7 @@ rb_ary_times(VALUE ary, VALUE times) https://github.com/ruby/ruby/blob/trunk/array.c#L4819
 
     len = NUM2LONG(times);
     if (len == 0) {
-	ary2 = ary_new(rb_obj_class(ary), 0);
+        ary2 = ary_new(rb_cArray, 0);
 	goto out;
     }
     if (len < 0) {
@@ -4831,7 +4830,7 @@ rb_ary_times(VALUE ary, VALUE times) https://github.com/ruby/ruby/blob/trunk/array.c#L4830
     }
     len *= RARRAY_LEN(ary);
 
-    ary2 = ary_new(rb_obj_class(ary), len);
+    ary2 = ary_new(rb_cArray, len);
     ARY_SET_LEN(ary2, len);
 
     ptr = RARRAY_CONST_PTR_TRANSIENT(ary);
@@ -5947,7 +5946,6 @@ rb_ary_uniq(VALUE ary) https://github.com/ruby/ruby/blob/trunk/array.c#L5946
 	hash = ary_make_hash(ary);
 	uniq = rb_hash_values(hash);
     }
-    RBASIC_SET_CLASS(uniq, rb_obj_class(ary));
     if (hash) {
         ary_recycle_hash(hash);
     }
@@ -6146,7 +6144,7 @@ flatten(VALUE ary, int level) https://github.com/ruby/ruby/blob/trunk/array.c#L6144
 	st_clear(memo);
     }
 
-    RBASIC_SET_CLASS(result, rb_obj_class(ary));
+    RBASIC_SET_CLASS(result, rb_cArray);
     return result;
 }
 
diff --git a/spec/ruby/core/array/flatten_spec.rb b/spec/ruby/core/array/flatten_spec.rb
index e7cd114..b2aa015 100644
--- a/spec/ruby/core/array/flatten_spec.rb
+++ b/spec/ruby/core/array/flatten_spec.rb
@@ -75,12 +75,24 @@ describe "Array#flatten" do https://github.com/ruby/ruby/blob/trunk/spec/ruby/core/array/flatten_spec.rb#L75
     [[obj]].flatten(1)
   end
 
-  it "returns subclass instance for Array subclasses" do
-    ArraySpecs::MyArray[].flatten.should be_an_instance_of(ArraySpecs::MyArray)
-    ArraySpecs::MyArray[1, 2, 3].flatten.should be_an_instance_of(ArraySpecs::MyArray)
-    ArraySpecs::MyArray[1, [2], 3].flatten.should be_an_instance_of(ArraySpecs::MyArray)
-    ArraySpecs::MyArray[1, [2, 3], 4].flatten.should == ArraySpecs::MyArray[1, 2, 3, 4]
-    [ArraySpecs::MyArray[1, 2, 3]].flatten.should be_an_instance_of(Array)
+  ruby_version_is ''...'3.0' do
+    it "returns subclass instance for Array subclasses" do
+      ArraySpecs::MyArray[].flatten.should be_an_instance_of(ArraySpecs::MyArray)
+      ArraySpecs::MyArray[1, 2, 3].flatten.should be_an_instance_of(ArraySpecs::MyArray)
+      ArraySpecs::MyArray[1, [2], 3].flatten.should be_an_instance_of(ArraySpecs::MyArray)
+      ArraySpecs::MyArray[1, [2, 3], 4].flatten.should == ArraySpecs::MyArray[1, 2, 3, 4]
+      [ArraySpecs::MyArray[1, 2, 3]].flatten.should be_an_instance_of(Array)
+    end
+  end
+
+  ruby_version_is '3.0' do
+    it "returns Array instance for Array subclasses" do
+      ArraySpecs::MyArray[].flatten.should be_an_instance_of(Array)
+      ArraySpecs::MyArray[1, 2, 3].flatten.should be_an_instance_of(Array)
+      ArraySpecs::MyArray[1, [2], 3].flatten.should be_an_instance_of(Array)
+      ArraySpecs::MyArray[1, [2, 3], 4].flatten.should == Array[1, 2, 3, 4]
+      [ArraySpecs::MyArray[1, 2, 3]].flatten.should be_an_instance_of(Array)
+    end
   end
 
   it "is not destructive" do
diff --git a/spec/ruby/core/array/multiply_spec.rb b/spec/ruby/core/array/multiply_spec.rb
index 8ccec13..16e4073 100644
--- a/spec/ruby/core/array/multiply_spec.rb
+++ b/spec/ruby/core/array/multiply_spec.rb
@@ -76,10 +76,20 @@ describe "Array#* with an integer" do https://github.com/ruby/ruby/blob/trunk/spec/ruby/core/array/multiply_spec.rb#L76
       @array = ArraySpecs::MyArray[1, 2, 3, 4, 5]
     end
 
-    it "returns a subclass instance" do
-      (@array * 0).should be_an_instance_of(ArraySpecs::MyArray)
-      (@array * 1).should be_an_instance_of(ArraySpecs::MyArray)
-      (@array * 2).should be_an_instance_of(ArraySpecs::MyArray)
+    ruby_version_is ''...'3.0' do
+      it "returns a subclass instance" do
+        (@array * 0).should be_an_instance_of(ArraySpecs::MyArray)
+        (@array * 1).should be_an_instance_of(ArraySpecs::MyArray)
+        (@array * 2).should be_an_instance_of(ArraySpecs::MyArray)
+      end
+    end
+
+    ruby_version_is '3.0' do
+      it "returns an Array instance" do
+        (@array * 0).should be_an_instance_of(Array)
+        (@array * 1).should be_an_instance_of(Array)
+        (@array * 2).should be_an_instance_of(Array)
+      end
     end
 
     it "does not call #initialize on the subclass instance" do
diff --git a/spec/ruby/core/array/shared/slice.rb b/spec/ruby/core/array/shared/slice.rb
index f36890f..845be76 100644
--- a/spec/ruby/core/array/shared/slice.rb
+++ b/spec/ruby/core/array/shared/slice.rb
@@ -397,28 +397,56 @@ describe :array_slice, shared: true do https://github.com/ruby/ruby/blob/trunk/spec/ruby/core/array/shared/slice.rb#L397
       @array = ArraySpecs::MyArray[1, 2, 3, 4, 5]
     end
 
-    it "returns a subclass instance with [n, m]" do
-      @array.send(@method, 0, 2).should be_an_instance_of(ArraySpecs::MyArray)
+    ruby_version_is ''...'3.0' do
+      it "returns a subclass instance with [n, m]" do
+        @array.send(@method, 0, 2).should be_an_instance_of(ArraySpecs::MyArray)
+      end
+
+      it "returns a subclass instance with [-n, m]" do
+        @array.send(@method, -3, 2).should be_an_instance_of(ArraySpecs::MyArray)
+      end
+
+      it "returns a subclass instance with [n..m]" do
+        @array.send(@method, 1..3).should be_an_instance_of(ArraySpecs::MyArray)
+      end
+
+      it "returns a subclass instance with [n...m]" do
+        @array.send(@method, 1...3).should be_an_instance_of(ArraySpecs::MyArray)
+      end
+
+      it "returns a subclass instance with [-n..-m]" do
+        @array.send(@method, -3..-1).should be_an_instance_of(ArraySpecs::MyArray)
+      end
+
+      it "returns a subclass instance with [-n...-m]" do
+        @array.send(@method, -3...-1).should be_an_instance_of(ArraySpecs::MyArray)
+      end
     end
 
-    it "returns a subclass instance with [-n, m]" do
-      @array.send(@method, -3, 2).should be_an_instance_of(ArraySpecs::MyArray)
-    end
+    ruby_version_is '3.0' do
+      it "returns a Array instance with [n, m]" do
+        @array.send(@method, 0, 2).should be_an_instance_of(Array)
+      end
 
-    it "returns a subclass instance with [n..m]" do
-      @array.send(@method, 1..3).should be_an_instance_of(ArraySpecs::MyArray)
-    end
+      it "returns a Array instance with [-n, m]" do
+        @array.send(@method, -3, 2).should be_an_instance_of(Array)
+      end
 
-    it "returns a subclass instance with [n...m]" do
-      @array.send(@method, 1...3).should be_an_instance_of(ArraySpecs::MyArray)
-    end
+      it "returns a Array instance with [n..m]" do
+        @array.send(@method, 1..3).should be_an_instance_of(Array)
+      end
 
-    it "returns a subclass instance with [-n..-m]" do
-      @array.send(@method, -3..-1).should be_an_instance_of(ArraySpecs::MyArray)
-    end
+      it "returns a Array instance with [n...m]" do
+        @array.send(@method, 1...3).should be_an_instance_of(Array)
+      end
+
+      it "returns a Array instance with [-n..-m]" do
+        @array.send(@method, -3..-1).should be_an_instance_of(Array)
+      end
 
-    it "returns a subclass instance with [-n...-m]" do
-      @array.send(@method, -3...-1).should be_an_instance_of(ArraySpecs::MyArray)
+      it "returns a Array instance with [-n...-m]" do
+        @array.send(@method, -3...-1).should be_an_instance_of(Array)
+      end
     end
 
     it "returns an empty array when m == n with [m...n]" do
diff --git a/spec/ruby/core/array/uniq_spec.rb b/spec/ruby/core/array/uniq_spec.rb
index fd60498..5911c23 100644
--- a/spec/ruby/core/array/uniq_spec.rb
+++ b/spec/ruby/core/array/uniq_spec.rb
@@ -128,8 +128,16 @@ describe "Array#uniq" do https://github.com/ruby/ruby/blob/trunk/spec/ruby/core/array/uniq_spec.rb#L128
     [false, nil, 42].uniq { :bar }.should == [false]
   end
 
-  it "returns subclass instance on Array subclasses" do
-    ArraySpecs::MyArray[1, 2, 3].uniq.should be_an_instance_of(ArraySpecs::MyArray)
+  ruby_version_is ''...'3.0' do
+    it "returns subclass instance on Array subclasses" do
+      ArraySpecs::MyArray[1, 2, 3].uniq.should be_an_instance_of(ArraySpecs::MyArray)
+    end
+  end
+
+  ruby_version_is '3.0' do
+    it "returns Array instance on Array subclasses" do
+      ArraySpecs::MyArray[1, 2, 3].uniq.should be_an_instance_of(Array)
+    end (... truncated)

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

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