ruby-changes:63667
From: Jeremy <ko1@a...>
Date: Sat, 21 Nov 2020 09:30:45 +0900 (JST)
Subject: [ruby-changes:63667] 58325daae3 (master): Make String methods return String instances when called on a subclass instance
https://git.ruby-lang.org/ruby.git/commit/?id=58325daae3 From 58325daae3beefda13ed100782cd19a89cc68771 Mon Sep 17 00:00:00 2001 From: Jeremy Evans <code@j...> Date: Sat, 24 Oct 2020 11:52:30 -0700 Subject: Make String methods return String instances when called on a subclass instance This modifies the following String methods to return String instances instead of subclass instances: * String#* * String#capitalize * String#center * String#chomp * String#chop * String#delete * String#delete_prefix * String#delete_suffix * String#downcase * String#dump * String#each/#each_line * String#gsub * String#ljust * String#lstrip * String#partition * String#reverse * String#rjust * String#rpartition * String#rstrip * String#scrub * String#slice! * String#slice/#[] * String#split * String#squeeze * String#strip * String#sub * String#succ/#next * String#swapcase * String#tr * String#tr_s * String#upcase This also fixes a bug in String#swapcase where it would return the receiver instead of a copy of the receiver if the receiver was the empty string. Some string methods were left to return subclass instances: * String#+@ * String#-@ Both of these methods will return the receiver (subclass instance) in some cases, so it is best to keep the returned class consistent. Fixes [#10845] diff --git a/spec/ruby/core/string/capitalize_spec.rb b/spec/ruby/core/string/capitalize_spec.rb index e6cf365..21df18a 100644 --- a/spec/ruby/core/string/capitalize_spec.rb +++ b/spec/ruby/core/string/capitalize_spec.rb @@ -80,9 +80,18 @@ describe "String#capitalize" do https://github.com/ruby/ruby/blob/trunk/spec/ruby/core/string/capitalize_spec.rb#L80 -> { "abc".capitalize(:invalid_option) }.should raise_error(ArgumentError) end - it "returns subclass instances when called on a subclass" do - StringSpecs::MyString.new("hello").capitalize.should be_an_instance_of(StringSpecs::MyString) - StringSpecs::MyString.new("Hello").capitalize.should be_an_instance_of(StringSpecs::MyString) + ruby_version_is ''...'3.0' do + it "returns subclass instances when called on a subclass" do + StringSpecs::MyString.new("hello").capitalize.should be_an_instance_of(StringSpecs::MyString) + StringSpecs::MyString.new("Hello").capitalize.should be_an_instance_of(StringSpecs::MyString) + end + end + + ruby_version_is '3.0' do + it "returns String instances when called on a subclass" do + StringSpecs::MyString.new("hello").capitalize.should be_an_instance_of(String) + StringSpecs::MyString.new("Hello").capitalize.should be_an_instance_of(String) + end end end diff --git a/spec/ruby/core/string/center_spec.rb b/spec/ruby/core/string/center_spec.rb index 8a4be0a..b660151 100644 --- a/spec/ruby/core/string/center_spec.rb +++ b/spec/ruby/core/string/center_spec.rb @@ -91,13 +91,26 @@ describe "String#center with length, padding" do https://github.com/ruby/ruby/blob/trunk/spec/ruby/core/string/center_spec.rb#L91 -> { "hello".center(0, "") }.should raise_error(ArgumentError) end - it "returns subclass instances when called on subclasses" do - StringSpecs::MyString.new("").center(10).should be_an_instance_of(StringSpecs::MyString) - StringSpecs::MyString.new("foo").center(10).should be_an_instance_of(StringSpecs::MyString) - StringSpecs::MyString.new("foo").center(10, StringSpecs::MyString.new("x")).should be_an_instance_of(StringSpecs::MyString) + ruby_version_is ''...'3.0' do + it "returns subclass instances when called on subclasses" do + StringSpecs::MyString.new("").center(10).should be_an_instance_of(StringSpecs::MyString) + StringSpecs::MyString.new("foo").center(10).should be_an_instance_of(StringSpecs::MyString) + StringSpecs::MyString.new("foo").center(10, StringSpecs::MyString.new("x")).should be_an_instance_of(StringSpecs::MyString) + + "".center(10, StringSpecs::MyString.new("x")).should be_an_instance_of(String) + "foo".center(10, StringSpecs::MyString.new("x")).should be_an_instance_of(String) + end + end - "".center(10, StringSpecs::MyString.new("x")).should be_an_instance_of(String) - "foo".center(10, StringSpecs::MyString.new("x")).should be_an_instance_of(String) + ruby_version_is '3.0' do + it "returns String instances when called on subclasses" do + StringSpecs::MyString.new("").center(10).should be_an_instance_of(String) + StringSpecs::MyString.new("foo").center(10).should be_an_instance_of(String) + StringSpecs::MyString.new("foo").center(10, StringSpecs::MyString.new("x")).should be_an_instance_of(String) + + "".center(10, StringSpecs::MyString.new("x")).should be_an_instance_of(String) + "foo".center(10, StringSpecs::MyString.new("x")).should be_an_instance_of(String) + end end ruby_version_is ''...'2.7' do diff --git a/spec/ruby/core/string/chomp_spec.rb b/spec/ruby/core/string/chomp_spec.rb index 7a1118d..3d6207f 100644 --- a/spec/ruby/core/string/chomp_spec.rb +++ b/spec/ruby/core/string/chomp_spec.rb @@ -46,9 +46,18 @@ describe "String#chomp" do https://github.com/ruby/ruby/blob/trunk/spec/ruby/core/string/chomp_spec.rb#L46 end end - it "returns subclass instances when called on a subclass" do - str = StringSpecs::MyString.new("hello\n").chomp - str.should be_an_instance_of(StringSpecs::MyString) + ruby_version_is ''...'3.0' do + it "returns subclass instances when called on a subclass" do + str = StringSpecs::MyString.new("hello\n").chomp + str.should be_an_instance_of(StringSpecs::MyString) + end + end + + ruby_version_is '3.0' do + it "returns String instances when called on a subclass" do + str = StringSpecs::MyString.new("hello\n").chomp + str.should be_an_instance_of(String) + end end it "removes trailing characters that match $/ when it has been assigned a value" do diff --git a/spec/ruby/core/string/chop_spec.rb b/spec/ruby/core/string/chop_spec.rb index 582d3c5..9b4e736 100644 --- a/spec/ruby/core/string/chop_spec.rb +++ b/spec/ruby/core/string/chop_spec.rb @@ -61,8 +61,16 @@ describe "String#chop" do https://github.com/ruby/ruby/blob/trunk/spec/ruby/core/string/chop_spec.rb#L61 end end - it "returns subclass instances when called on a subclass" do - StringSpecs::MyString.new("hello\n").chop.should be_an_instance_of(StringSpecs::MyString) + ruby_version_is ''...'3.0' do + it "returns subclass instances when called on a subclass" do + StringSpecs::MyString.new("hello\n").chop.should be_an_instance_of(StringSpecs::MyString) + end + end + + ruby_version_is '3.0' do + it "returns String instances when called on a subclass" do + StringSpecs::MyString.new("hello\n").chop.should be_an_instance_of(String) + end end end diff --git a/spec/ruby/core/string/delete_prefix_spec.rb b/spec/ruby/core/string/delete_prefix_spec.rb index bd5b56a..8469791 100644 --- a/spec/ruby/core/string/delete_prefix_spec.rb +++ b/spec/ruby/core/string/delete_prefix_spec.rb @@ -41,9 +41,18 @@ describe "String#delete_prefix" do https://github.com/ruby/ruby/blob/trunk/spec/ruby/core/string/delete_prefix_spec.rb#L41 'hello'.delete_prefix(o).should == 'o' end - it "returns a subclass instance when called on a subclass instance" do - s = StringSpecs::MyString.new('hello') - s.delete_prefix('hell').should be_an_instance_of(StringSpecs::MyString) + ruby_version_is ''...'3.0' do + it "returns a subclass instance when called on a subclass instance" do + s = StringSpecs::MyString.new('hello') + s.delete_prefix('hell').should be_an_instance_of(StringSpecs::MyString) + end + end + + ruby_version_is '3.0' do + it "returns a String instance when called on a subclass instance" do + s = StringSpecs::MyString.new('hello') + s.delete_prefix('hell').should be_an_instance_of(String) + end end end diff --git a/spec/ruby/core/string/delete_spec.rb b/spec/ruby/core/string/delete_spec.rb index b6e54f8..ebca0b7 100644 --- a/spec/ruby/core/string/delete_spec.rb +++ b/spec/ruby/core/string/delete_spec.rb @@ -93,8 +93,16 @@ describe "String#delete" do https://github.com/ruby/ruby/blob/trunk/spec/ruby/core/string/delete_spec.rb#L93 -> { "hello world".delete(mock('x')) }.should raise_error(TypeError) end - it "returns subclass instances when called on a subclass" do - StringSpecs::MyString.new("oh no!!!").delete("!").should be_an_instance_of(StringSpecs::MyString) + ruby_version_is ''...'3.0' do + it "returns subclass instances when called on a subclass" do + StringSpecs::MyString.new("oh no!!!").delete("!").should be_an_instance_of(StringSpecs::MyString) + end + end + + ruby_version_is '3.0' do + it "returns String instances when called on a subclass" do + StringSpecs::MyString.new("oh no!!!").delete("!").should be_an_instance_of(String) + end end end diff --git a/spec/ruby/core/string/delete_suffix_spec.rb b/spec/ruby/core/string/delete_suffix_spec.rb index dbb5f9d..12d0ee1 100644 --- a/spec/ruby/core/string/delete_suffix_spec.rb +++ b/spec/ruby/core/string/delete_suffix_spec.rb @@ -41,9 +41,18 @@ describe "String#delete_suffix" do https://github.com/ruby/ruby/blob/trunk/spec/ruby/core/string/delete_suffix_spec.rb#L41 'hello'.delete_suffix(o).should == 'h' end - it "returns a subclass instance when called on a subclass instance" do - s = StringSpecs::MyString.new('hello') - s.delete_suffix('ello').should be_an_instance_of(StringSpecs::MyString) + ruby_version_is ''...'3.0' do + it "returns a subclass instance when called on a subclass instance" do + s = StringSpecs::MyString.new('hello') + s.delete_suffix('ello').should be_an_instance_of(StringSpecs::MyString) + end + end + + ruby_version_is '3.0' do + it "returns a String instance when called on a subclass instance" do + s = StringSpecs::MyString.new('hello') + s.delete_suffix('ello').should be_an_instance_of(String) + end end end diff (... truncated) -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/