зеркало из https://github.com/github/ruby.git
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]
This commit is contained in:
Родитель
4f5d14eb8c
Коммит
58325daae3
|
@ -80,9 +80,18 @@ describe "String#capitalize" do
|
|||
-> { "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
|
||||
|
||||
|
|
|
@ -91,13 +91,26 @@ describe "String#center with length, padding" do
|
|||
-> { "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)
|
||||
"".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 '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
|
||||
|
|
|
@ -46,9 +46,18 @@ describe "String#chomp" do
|
|||
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
|
||||
|
|
|
@ -61,8 +61,16 @@ describe "String#chop" do
|
|||
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
|
||||
|
||||
|
|
|
@ -41,9 +41,18 @@ describe "String#delete_prefix" do
|
|||
'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
|
||||
|
||||
|
|
|
@ -93,8 +93,16 @@ describe "String#delete" do
|
|||
-> { "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
|
||||
|
||||
|
|
|
@ -41,9 +41,18 @@ describe "String#delete_suffix" do
|
|||
'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
|
||||
|
||||
|
|
|
@ -76,8 +76,16 @@ describe "String#downcase" do
|
|||
end
|
||||
end
|
||||
|
||||
it "returns a subclass instance for subclasses" do
|
||||
StringSpecs::MyString.new("FOObar").downcase.should be_an_instance_of(StringSpecs::MyString)
|
||||
ruby_version_is ''...'3.0' do
|
||||
it "returns a subclass instance for subclasses" do
|
||||
StringSpecs::MyString.new("FOObar").downcase.should be_an_instance_of(StringSpecs::MyString)
|
||||
end
|
||||
end
|
||||
|
||||
ruby_version_is '3.0' do
|
||||
it "returns a String instance for subclasses" do
|
||||
StringSpecs::MyString.new("FOObar").downcase.should be_an_instance_of(String)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -19,8 +19,16 @@ describe "String#dump" do
|
|||
"foo".freeze.dump.should_not.frozen?
|
||||
end
|
||||
|
||||
it "returns a subclass instance" do
|
||||
StringSpecs::MyString.new.dump.should be_an_instance_of(StringSpecs::MyString)
|
||||
ruby_version_is ''...'3.0' do
|
||||
it "returns a subclass instance" do
|
||||
StringSpecs::MyString.new.dump.should be_an_instance_of(StringSpecs::MyString)
|
||||
end
|
||||
end
|
||||
|
||||
ruby_version_is '3.0' do
|
||||
it "returns a String instance" do
|
||||
StringSpecs::MyString.new.dump.should be_an_instance_of(String)
|
||||
end
|
||||
end
|
||||
|
||||
it "wraps string with \"" do
|
||||
|
|
|
@ -236,11 +236,22 @@ describe "String#gsub with pattern and replacement" do
|
|||
-> { "hello".gsub(/[aeiou]/, nil) }.should raise_error(TypeError)
|
||||
end
|
||||
|
||||
it "returns subclass instances when called on a subclass" do
|
||||
StringSpecs::MyString.new("").gsub(//, "").should be_an_instance_of(StringSpecs::MyString)
|
||||
StringSpecs::MyString.new("").gsub(/foo/, "").should be_an_instance_of(StringSpecs::MyString)
|
||||
StringSpecs::MyString.new("foo").gsub(/foo/, "").should be_an_instance_of(StringSpecs::MyString)
|
||||
StringSpecs::MyString.new("foo").gsub("foo", "").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("").gsub(//, "").should be_an_instance_of(StringSpecs::MyString)
|
||||
StringSpecs::MyString.new("").gsub(/foo/, "").should be_an_instance_of(StringSpecs::MyString)
|
||||
StringSpecs::MyString.new("foo").gsub(/foo/, "").should be_an_instance_of(StringSpecs::MyString)
|
||||
StringSpecs::MyString.new("foo").gsub("foo", "").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("").gsub(//, "").should be_an_instance_of(String)
|
||||
StringSpecs::MyString.new("").gsub(/foo/, "").should be_an_instance_of(String)
|
||||
StringSpecs::MyString.new("foo").gsub(/foo/, "").should be_an_instance_of(String)
|
||||
StringSpecs::MyString.new("foo").gsub("foo", "").should be_an_instance_of(String)
|
||||
end
|
||||
end
|
||||
|
||||
# Note: $~ cannot be tested because mspec messes with it
|
||||
|
|
|
@ -74,13 +74,26 @@ describe "String#ljust with length, padding" do
|
|||
-> { "hello".ljust(10, '') }.should raise_error(ArgumentError)
|
||||
end
|
||||
|
||||
it "returns subclass instances when called on subclasses" do
|
||||
StringSpecs::MyString.new("").ljust(10).should be_an_instance_of(StringSpecs::MyString)
|
||||
StringSpecs::MyString.new("foo").ljust(10).should be_an_instance_of(StringSpecs::MyString)
|
||||
StringSpecs::MyString.new("foo").ljust(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("").ljust(10).should be_an_instance_of(StringSpecs::MyString)
|
||||
StringSpecs::MyString.new("foo").ljust(10).should be_an_instance_of(StringSpecs::MyString)
|
||||
StringSpecs::MyString.new("foo").ljust(10, StringSpecs::MyString.new("x")).should be_an_instance_of(StringSpecs::MyString)
|
||||
|
||||
"".ljust(10, StringSpecs::MyString.new("x")).should be_an_instance_of(String)
|
||||
"foo".ljust(10, StringSpecs::MyString.new("x")).should be_an_instance_of(String)
|
||||
"".ljust(10, StringSpecs::MyString.new("x")).should be_an_instance_of(String)
|
||||
"foo".ljust(10, StringSpecs::MyString.new("x")).should be_an_instance_of(String)
|
||||
end
|
||||
end
|
||||
|
||||
ruby_version_is '3.0' do
|
||||
it "returns String instances when called on subclasses" do
|
||||
StringSpecs::MyString.new("").ljust(10).should be_an_instance_of(String)
|
||||
StringSpecs::MyString.new("foo").ljust(10).should be_an_instance_of(String)
|
||||
StringSpecs::MyString.new("foo").ljust(10, StringSpecs::MyString.new("x")).should be_an_instance_of(String)
|
||||
|
||||
"".ljust(10, StringSpecs::MyString.new("x")).should be_an_instance_of(String)
|
||||
"foo".ljust(10, StringSpecs::MyString.new("x")).should be_an_instance_of(String)
|
||||
end
|
||||
end
|
||||
|
||||
ruby_version_is ''...'2.7' do
|
||||
|
|
|
@ -74,13 +74,26 @@ describe "String#rjust with length, padding" do
|
|||
-> { "hello".rjust(10, '') }.should raise_error(ArgumentError)
|
||||
end
|
||||
|
||||
it "returns subclass instances when called on subclasses" do
|
||||
StringSpecs::MyString.new("").rjust(10).should be_an_instance_of(StringSpecs::MyString)
|
||||
StringSpecs::MyString.new("foo").rjust(10).should be_an_instance_of(StringSpecs::MyString)
|
||||
StringSpecs::MyString.new("foo").rjust(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("").rjust(10).should be_an_instance_of(StringSpecs::MyString)
|
||||
StringSpecs::MyString.new("foo").rjust(10).should be_an_instance_of(StringSpecs::MyString)
|
||||
StringSpecs::MyString.new("foo").rjust(10, StringSpecs::MyString.new("x")).should be_an_instance_of(StringSpecs::MyString)
|
||||
|
||||
"".rjust(10, StringSpecs::MyString.new("x")).should be_an_instance_of(String)
|
||||
"foo".rjust(10, StringSpecs::MyString.new("x")).should be_an_instance_of(String)
|
||||
"".rjust(10, StringSpecs::MyString.new("x")).should be_an_instance_of(String)
|
||||
"foo".rjust(10, StringSpecs::MyString.new("x")).should be_an_instance_of(String)
|
||||
end
|
||||
end
|
||||
|
||||
ruby_version_is '3.0' do
|
||||
it "returns String instances when called on subclasses" do
|
||||
StringSpecs::MyString.new("").rjust(10).should be_an_instance_of(String)
|
||||
StringSpecs::MyString.new("foo").rjust(10).should be_an_instance_of(String)
|
||||
StringSpecs::MyString.new("foo").rjust(10, StringSpecs::MyString.new("x")).should be_an_instance_of(String)
|
||||
|
||||
"".rjust(10, StringSpecs::MyString.new("x")).should be_an_instance_of(String)
|
||||
"foo".rjust(10, StringSpecs::MyString.new("x")).should be_an_instance_of(String)
|
||||
end
|
||||
end
|
||||
|
||||
ruby_version_is ''...'2.7' do
|
||||
|
|
|
@ -93,10 +93,20 @@ describe :string_each_line, shared: true do
|
|||
end
|
||||
end
|
||||
|
||||
it "yields subclass instances for subclasses" do
|
||||
a = []
|
||||
StringSpecs::MyString.new("hello\nworld").send(@method) { |s| a << s.class }
|
||||
a.should == [StringSpecs::MyString, StringSpecs::MyString]
|
||||
ruby_version_is ''...'3.0' do
|
||||
it "yields subclass instances for subclasses" do
|
||||
a = []
|
||||
StringSpecs::MyString.new("hello\nworld").send(@method) { |s| a << s.class }
|
||||
a.should == [StringSpecs::MyString, StringSpecs::MyString]
|
||||
end
|
||||
end
|
||||
|
||||
ruby_version_is '3.0' do
|
||||
it "yields String instances for subclasses" do
|
||||
a = []
|
||||
StringSpecs::MyString.new("hello\nworld").send(@method) { |s| a << s.class }
|
||||
a.should == [String, String]
|
||||
end
|
||||
end
|
||||
|
||||
it "returns self" do
|
||||
|
|
|
@ -163,11 +163,22 @@ describe :string_slice_index_length, shared: true do
|
|||
-> { "hello".send(@method, 0, bignum_value) }.should raise_error(RangeError)
|
||||
end
|
||||
|
||||
it "returns subclass instances" do
|
||||
s = StringSpecs::MyString.new("hello")
|
||||
s.send(@method, 0,0).should be_an_instance_of(StringSpecs::MyString)
|
||||
s.send(@method, 0,4).should be_an_instance_of(StringSpecs::MyString)
|
||||
s.send(@method, 1,4).should be_an_instance_of(StringSpecs::MyString)
|
||||
ruby_version_is ''...'3.0' do
|
||||
it "returns subclass instances" do
|
||||
s = StringSpecs::MyString.new("hello")
|
||||
s.send(@method, 0,0).should be_an_instance_of(StringSpecs::MyString)
|
||||
s.send(@method, 0,4).should be_an_instance_of(StringSpecs::MyString)
|
||||
s.send(@method, 1,4).should be_an_instance_of(StringSpecs::MyString)
|
||||
end
|
||||
end
|
||||
|
||||
ruby_version_is '3.0' do
|
||||
it "returns String instances" do
|
||||
s = StringSpecs::MyString.new("hello")
|
||||
s.send(@method, 0,0).should be_an_instance_of(String)
|
||||
s.send(@method, 0,4).should be_an_instance_of(String)
|
||||
s.send(@method, 1,4).should be_an_instance_of(String)
|
||||
end
|
||||
end
|
||||
|
||||
it "handles repeated application" do
|
||||
|
@ -252,11 +263,22 @@ describe :string_slice_range, shared: true do
|
|||
end
|
||||
end
|
||||
|
||||
it "returns subclass instances" do
|
||||
s = StringSpecs::MyString.new("hello")
|
||||
s.send(@method, 0...0).should be_an_instance_of(StringSpecs::MyString)
|
||||
s.send(@method, 0..4).should be_an_instance_of(StringSpecs::MyString)
|
||||
s.send(@method, 1..4).should be_an_instance_of(StringSpecs::MyString)
|
||||
ruby_version_is ''...'3.0' do
|
||||
it "returns subclass instances" do
|
||||
s = StringSpecs::MyString.new("hello")
|
||||
s.send(@method, 0...0).should be_an_instance_of(StringSpecs::MyString)
|
||||
s.send(@method, 0..4).should be_an_instance_of(StringSpecs::MyString)
|
||||
s.send(@method, 1..4).should be_an_instance_of(StringSpecs::MyString)
|
||||
end
|
||||
end
|
||||
|
||||
ruby_version_is '3.0' do
|
||||
it "returns String instances" do
|
||||
s = StringSpecs::MyString.new("hello")
|
||||
s.send(@method, 0...0).should be_an_instance_of(String)
|
||||
s.send(@method, 0..4).should be_an_instance_of(String)
|
||||
s.send(@method, 1..4).should be_an_instance_of(String)
|
||||
end
|
||||
end
|
||||
|
||||
it "calls to_int on range arguments" do
|
||||
|
@ -348,10 +370,20 @@ describe :string_slice_regexp, shared: true do
|
|||
end
|
||||
end
|
||||
|
||||
it "returns subclass instances" do
|
||||
s = StringSpecs::MyString.new("hello")
|
||||
s.send(@method, //).should be_an_instance_of(StringSpecs::MyString)
|
||||
s.send(@method, /../).should be_an_instance_of(StringSpecs::MyString)
|
||||
ruby_version_is ''...'3.0' do
|
||||
it "returns subclass instances" do
|
||||
s = StringSpecs::MyString.new("hello")
|
||||
s.send(@method, //).should be_an_instance_of(StringSpecs::MyString)
|
||||
s.send(@method, /../).should be_an_instance_of(StringSpecs::MyString)
|
||||
end
|
||||
end
|
||||
|
||||
ruby_version_is '3.0' do
|
||||
it "returns String instances" do
|
||||
s = StringSpecs::MyString.new("hello")
|
||||
s.send(@method, //).should be_an_instance_of(String)
|
||||
s.send(@method, /../).should be_an_instance_of(String)
|
||||
end
|
||||
end
|
||||
|
||||
it "sets $~ to MatchData when there is a match and nil when there's none" do
|
||||
|
@ -436,10 +468,20 @@ describe :string_slice_regexp_index, shared: true do
|
|||
-> { "hello".send(@method, /(.)(.)(.)/, nil) }.should raise_error(TypeError)
|
||||
end
|
||||
|
||||
it "returns subclass instances" do
|
||||
s = StringSpecs::MyString.new("hello")
|
||||
s.send(@method, /(.)(.)/, 0).should be_an_instance_of(StringSpecs::MyString)
|
||||
s.send(@method, /(.)(.)/, 1).should be_an_instance_of(StringSpecs::MyString)
|
||||
ruby_version_is ''...'3.0' do
|
||||
it "returns subclass instances" do
|
||||
s = StringSpecs::MyString.new("hello")
|
||||
s.send(@method, /(.)(.)/, 0).should be_an_instance_of(StringSpecs::MyString)
|
||||
s.send(@method, /(.)(.)/, 1).should be_an_instance_of(StringSpecs::MyString)
|
||||
end
|
||||
end
|
||||
|
||||
ruby_version_is '3.0' do
|
||||
it "returns String instances" do
|
||||
s = StringSpecs::MyString.new("hello")
|
||||
s.send(@method, /(.)(.)/, 0).should be_an_instance_of(String)
|
||||
s.send(@method, /(.)(.)/, 1).should be_an_instance_of(String)
|
||||
end
|
||||
end
|
||||
|
||||
it "sets $~ to MatchData when there is a match and nil when there's none" do
|
||||
|
@ -493,11 +535,22 @@ describe :string_slice_string, shared: true do
|
|||
-> { "hello".send(@method, o) }.should raise_error(TypeError)
|
||||
end
|
||||
|
||||
it "returns a subclass instance when given a subclass instance" do
|
||||
s = StringSpecs::MyString.new("el")
|
||||
r = "hello".send(@method, s)
|
||||
r.should == "el"
|
||||
r.should be_an_instance_of(StringSpecs::MyString)
|
||||
ruby_version_is ''...'3.0' do
|
||||
it "returns a subclass instance when given a subclass instance" do
|
||||
s = StringSpecs::MyString.new("el")
|
||||
r = "hello".send(@method, s)
|
||||
r.should == "el"
|
||||
r.should be_an_instance_of(StringSpecs::MyString)
|
||||
end
|
||||
end
|
||||
|
||||
ruby_version_is '3.0' do
|
||||
it "returns a String instance when given a subclass instance" do
|
||||
s = StringSpecs::MyString.new("el")
|
||||
r = "hello".send(@method, s)
|
||||
r.should == "el"
|
||||
r.should be_an_instance_of(String)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -567,9 +620,18 @@ describe :string_slice_regexp_group, shared: true do
|
|||
-> { "hello".send(@method, /(?<q>)/, '') }.should raise_error(IndexError)
|
||||
end
|
||||
|
||||
it "returns subclass instances" do
|
||||
s = StringSpecs::MyString.new("hello")
|
||||
s.send(@method, /(?<q>.)/, 'q').should be_an_instance_of(StringSpecs::MyString)
|
||||
ruby_version_is ''...'3.0' do
|
||||
it "returns subclass instances" do
|
||||
s = StringSpecs::MyString.new("hello")
|
||||
s.send(@method, /(?<q>.)/, 'q').should be_an_instance_of(StringSpecs::MyString)
|
||||
end
|
||||
end
|
||||
|
||||
ruby_version_is '3.0' do
|
||||
it "returns String instances" do
|
||||
s = StringSpecs::MyString.new("hello")
|
||||
s.send(@method, /(?<q>.)/, 'q').should be_an_instance_of(String)
|
||||
end
|
||||
end
|
||||
|
||||
it "sets $~ to MatchData when there is a match and nil when there's none" do
|
||||
|
|
|
@ -59,10 +59,20 @@ describe :string_succ, shared: true do
|
|||
"\xFF\xFF".send(@method).should == "\x01\x00\x00"
|
||||
end
|
||||
|
||||
it "returns subclass instances when called on a subclass" do
|
||||
StringSpecs::MyString.new("").send(@method).should be_an_instance_of(StringSpecs::MyString)
|
||||
StringSpecs::MyString.new("a").send(@method).should be_an_instance_of(StringSpecs::MyString)
|
||||
StringSpecs::MyString.new("z").send(@method).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("").send(@method).should be_an_instance_of(StringSpecs::MyString)
|
||||
StringSpecs::MyString.new("a").send(@method).should be_an_instance_of(StringSpecs::MyString)
|
||||
StringSpecs::MyString.new("z").send(@method).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("").send(@method).should be_an_instance_of(String)
|
||||
StringSpecs::MyString.new("a").send(@method).should be_an_instance_of(String)
|
||||
StringSpecs::MyString.new("z").send(@method).should be_an_instance_of(String)
|
||||
end
|
||||
end
|
||||
|
||||
ruby_version_is ''...'2.7' do
|
||||
|
|
|
@ -142,12 +142,21 @@ describe "String#slice! with index, length" do
|
|||
"hello".slice!(obj, obj).should == "ll"
|
||||
end
|
||||
|
||||
it "returns subclass instances" do
|
||||
s = StringSpecs::MyString.new("hello")
|
||||
s.slice!(0, 0).should be_an_instance_of(StringSpecs::MyString)
|
||||
s.slice!(0, 4).should be_an_instance_of(StringSpecs::MyString)
|
||||
ruby_version_is ''...'3.0' do
|
||||
it "returns subclass instances" do
|
||||
s = StringSpecs::MyString.new("hello")
|
||||
s.slice!(0, 0).should be_an_instance_of(StringSpecs::MyString)
|
||||
s.slice!(0, 4).should be_an_instance_of(StringSpecs::MyString)
|
||||
end
|
||||
end
|
||||
|
||||
ruby_version_is '3.0' do
|
||||
it "returns String instances" do
|
||||
s = StringSpecs::MyString.new("hello")
|
||||
s.slice!(0, 0).should be_an_instance_of(String)
|
||||
s.slice!(0, 4).should be_an_instance_of(String)
|
||||
end
|
||||
end
|
||||
|
||||
it "returns the substring given by the character offsets" do
|
||||
"hellö there".slice!(1,0).should == ""
|
||||
|
@ -196,10 +205,20 @@ describe "String#slice! Range" do
|
|||
end
|
||||
end
|
||||
|
||||
it "returns subclass instances" do
|
||||
s = StringSpecs::MyString.new("hello")
|
||||
s.slice!(0...0).should be_an_instance_of(StringSpecs::MyString)
|
||||
s.slice!(0..4).should be_an_instance_of(StringSpecs::MyString)
|
||||
ruby_version_is ''...'3.0' do
|
||||
it "returns subclass instances" do
|
||||
s = StringSpecs::MyString.new("hello")
|
||||
s.slice!(0...0).should be_an_instance_of(StringSpecs::MyString)
|
||||
s.slice!(0..4).should be_an_instance_of(StringSpecs::MyString)
|
||||
end
|
||||
end
|
||||
|
||||
ruby_version_is '3.0' do
|
||||
it "returns String instances" do
|
||||
s = StringSpecs::MyString.new("hello")
|
||||
s.slice!(0...0).should be_an_instance_of(String)
|
||||
s.slice!(0..4).should be_an_instance_of(String)
|
||||
end
|
||||
end
|
||||
|
||||
it "calls to_int on range arguments" do
|
||||
|
@ -299,10 +318,20 @@ describe "String#slice! with Regexp" do
|
|||
end
|
||||
end
|
||||
|
||||
it "returns subclass instances" do
|
||||
s = StringSpecs::MyString.new("hello")
|
||||
s.slice!(//).should be_an_instance_of(StringSpecs::MyString)
|
||||
s.slice!(/../).should be_an_instance_of(StringSpecs::MyString)
|
||||
ruby_version_is ''...'3.0' do
|
||||
it "returns subclass instances" do
|
||||
s = StringSpecs::MyString.new("hello")
|
||||
s.slice!(//).should be_an_instance_of(StringSpecs::MyString)
|
||||
s.slice!(/../).should be_an_instance_of(StringSpecs::MyString)
|
||||
end
|
||||
end
|
||||
|
||||
ruby_version_is '3.0' do
|
||||
it "returns String instances" do
|
||||
s = StringSpecs::MyString.new("hello")
|
||||
s.slice!(//).should be_an_instance_of(String)
|
||||
s.slice!(/../).should be_an_instance_of(String)
|
||||
end
|
||||
end
|
||||
|
||||
it "returns the matching portion of self with a multi byte character" do
|
||||
|
@ -383,10 +412,20 @@ describe "String#slice! with Regexp, index" do
|
|||
"har".slice!(/(.)(.)(.)/, obj).should == "a"
|
||||
end
|
||||
|
||||
it "returns subclass instances" do
|
||||
s = StringSpecs::MyString.new("hello")
|
||||
s.slice!(/(.)(.)/, 0).should be_an_instance_of(StringSpecs::MyString)
|
||||
s.slice!(/(.)(.)/, 1).should be_an_instance_of(StringSpecs::MyString)
|
||||
ruby_version_is ''...'3.0' do
|
||||
it "returns subclass instances" do
|
||||
s = StringSpecs::MyString.new("hello")
|
||||
s.slice!(/(.)(.)/, 0).should be_an_instance_of(StringSpecs::MyString)
|
||||
s.slice!(/(.)(.)/, 1).should be_an_instance_of(StringSpecs::MyString)
|
||||
end
|
||||
end
|
||||
|
||||
ruby_version_is '3.0' do
|
||||
it "returns String instances" do
|
||||
s = StringSpecs::MyString.new("hello")
|
||||
s.slice!(/(.)(.)/, 0).should be_an_instance_of(String)
|
||||
s.slice!(/(.)(.)/, 1).should be_an_instance_of(String)
|
||||
end
|
||||
end
|
||||
|
||||
it "returns the encoding aware capture for the given index" do
|
||||
|
@ -461,11 +500,22 @@ describe "String#slice! with String" do
|
|||
-> { "hello".slice!(o) }.should raise_error(TypeError)
|
||||
end
|
||||
|
||||
it "returns a subclass instance when given a subclass instance" do
|
||||
s = StringSpecs::MyString.new("el")
|
||||
r = "hello".slice!(s)
|
||||
r.should == "el"
|
||||
r.should be_an_instance_of(StringSpecs::MyString)
|
||||
ruby_version_is ''...'3.0' do
|
||||
it "returns a subclass instance when given a subclass instance" do
|
||||
s = StringSpecs::MyString.new("el")
|
||||
r = "hello".slice!(s)
|
||||
r.should == "el"
|
||||
r.should be_an_instance_of(StringSpecs::MyString)
|
||||
end
|
||||
end
|
||||
|
||||
ruby_version_is '3.0' do
|
||||
it "returns a subclass instance when given a subclass instance" do
|
||||
s = StringSpecs::MyString.new("el")
|
||||
r = "hello".slice!(s)
|
||||
r.should == "el"
|
||||
r.should be_an_instance_of(String)
|
||||
end
|
||||
end
|
||||
|
||||
it "raises a FrozenError if self is frozen" do
|
||||
|
|
|
@ -159,28 +159,48 @@ describe "String#split with String" do
|
|||
"foo".split("bar", 3).should == ["foo"]
|
||||
end
|
||||
|
||||
it "returns subclass instances based on self" do
|
||||
["", "x.y.z.", " x y "].each do |str|
|
||||
["", ".", " "].each do |pat|
|
||||
[-1, 0, 1, 2].each do |limit|
|
||||
StringSpecs::MyString.new(str).split(pat, limit).each do |x|
|
||||
x.should be_an_instance_of(StringSpecs::MyString)
|
||||
end
|
||||
ruby_version_is ''...'3.0' do
|
||||
it "returns subclass instances based on self" do
|
||||
["", "x.y.z.", " x y "].each do |str|
|
||||
["", ".", " "].each do |pat|
|
||||
[-1, 0, 1, 2].each do |limit|
|
||||
StringSpecs::MyString.new(str).split(pat, limit).each do |x|
|
||||
x.should be_an_instance_of(StringSpecs::MyString)
|
||||
end
|
||||
|
||||
str.split(StringSpecs::MyString.new(pat), limit).each do |x|
|
||||
x.should be_an_instance_of(String)
|
||||
str.split(StringSpecs::MyString.new(pat), limit).each do |x|
|
||||
x.should be_an_instance_of(String)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it "does not call constructor on created subclass instances" do
|
||||
# can't call should_not_receive on an object that doesn't yet exist
|
||||
# so failure here is signalled by exception, not expectation failure
|
||||
|
||||
s = StringSpecs::StringWithRaisingConstructor.new('silly:string')
|
||||
s.split(':').first.should == 'silly'
|
||||
end
|
||||
end
|
||||
|
||||
it "does not call constructor on created subclass instances" do
|
||||
# can't call should_not_receive on an object that doesn't yet exist
|
||||
# so failure here is signalled by exception, not expectation failure
|
||||
ruby_version_is '3.0' do
|
||||
it "returns String instances based on self" do
|
||||
["", "x.y.z.", " x y "].each do |str|
|
||||
["", ".", " "].each do |pat|
|
||||
[-1, 0, 1, 2].each do |limit|
|
||||
StringSpecs::MyString.new(str).split(pat, limit).each do |x|
|
||||
x.should be_an_instance_of(String)
|
||||
end
|
||||
|
||||
s = StringSpecs::StringWithRaisingConstructor.new('silly:string')
|
||||
s.split(':').first.should == 'silly'
|
||||
str.split(StringSpecs::MyString.new(pat), limit).each do |x|
|
||||
x.should be_an_instance_of(String)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
ruby_version_is ''...'2.7' do
|
||||
|
@ -355,24 +375,40 @@ describe "String#split with Regexp" do
|
|||
"foo".split(/bar/, 3).should == ["foo"]
|
||||
end
|
||||
|
||||
it "returns subclass instances based on self" do
|
||||
["", "x:y:z:", " x y "].each do |str|
|
||||
[//, /:/, /\s+/].each do |pat|
|
||||
[-1, 0, 1, 2].each do |limit|
|
||||
StringSpecs::MyString.new(str).split(pat, limit).each do |x|
|
||||
x.should be_an_instance_of(StringSpecs::MyString)
|
||||
ruby_version_is ''...'3.0' do
|
||||
it "returns subclass instances based on self" do
|
||||
["", "x:y:z:", " x y "].each do |str|
|
||||
[//, /:/, /\s+/].each do |pat|
|
||||
[-1, 0, 1, 2].each do |limit|
|
||||
StringSpecs::MyString.new(str).split(pat, limit).each do |x|
|
||||
x.should be_an_instance_of(StringSpecs::MyString)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it "does not call constructor on created subclass instances" do
|
||||
# can't call should_not_receive on an object that doesn't yet exist
|
||||
# so failure here is signalled by exception, not expectation failure
|
||||
|
||||
s = StringSpecs::StringWithRaisingConstructor.new('silly:string')
|
||||
s.split(/:/).first.should == 'silly'
|
||||
end
|
||||
end
|
||||
|
||||
it "does not call constructor on created subclass instances" do
|
||||
# can't call should_not_receive on an object that doesn't yet exist
|
||||
# so failure here is signalled by exception, not expectation failure
|
||||
|
||||
s = StringSpecs::StringWithRaisingConstructor.new('silly:string')
|
||||
s.split(/:/).first.should == 'silly'
|
||||
ruby_version_is '3.0' do
|
||||
it "returns String instances based on self" do
|
||||
["", "x:y:z:", " x y "].each do |str|
|
||||
[//, /:/, /\s+/].each do |pat|
|
||||
[-1, 0, 1, 2].each do |limit|
|
||||
StringSpecs::MyString.new(str).split(pat, limit).each do |x|
|
||||
x.should be_an_instance_of(String)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
ruby_version_is ''...'2.7' do
|
||||
|
@ -493,16 +529,32 @@ describe "String#split with Regexp" do
|
|||
end
|
||||
|
||||
describe "for a String subclass" do
|
||||
it "yields instances of the same subclass" do
|
||||
a = []
|
||||
StringSpecs::MyString.new("a|b").split("|") { |str| a << str }
|
||||
first, last = a
|
||||
ruby_version_is ''...'3.0' do
|
||||
it "yields instances of the same subclass" do
|
||||
a = []
|
||||
StringSpecs::MyString.new("a|b").split("|") { |str| a << str }
|
||||
first, last = a
|
||||
|
||||
first.should be_an_instance_of(StringSpecs::MyString)
|
||||
first.should == "a"
|
||||
first.should be_an_instance_of(StringSpecs::MyString)
|
||||
first.should == "a"
|
||||
|
||||
last.should be_an_instance_of(StringSpecs::MyString)
|
||||
last.should == "b"
|
||||
last.should be_an_instance_of(StringSpecs::MyString)
|
||||
last.should == "b"
|
||||
end
|
||||
end
|
||||
|
||||
ruby_version_is '3.0' do
|
||||
it "yields instances of String" do
|
||||
a = []
|
||||
StringSpecs::MyString.new("a|b").split("|") { |str| a << str }
|
||||
first, last = a
|
||||
|
||||
first.should be_an_instance_of(String)
|
||||
first.should == "a"
|
||||
|
||||
last.should be_an_instance_of(String)
|
||||
last.should == "b"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -80,8 +80,16 @@ describe "String#squeeze" do
|
|||
-> { "hello world".squeeze(mock('x')) }.should raise_error(TypeError)
|
||||
end
|
||||
|
||||
it "returns subclass instances when called on a subclass" do
|
||||
StringSpecs::MyString.new("oh no!!!").squeeze("!").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!!!").squeeze("!").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!!!").squeeze("!").should be_an_instance_of(String)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -192,11 +192,22 @@ describe "String#sub with pattern, replacement" do
|
|||
-> { "hello".sub(/[aeiou]/, 99) }.should raise_error(TypeError)
|
||||
end
|
||||
|
||||
it "returns subclass instances when called on a subclass" do
|
||||
StringSpecs::MyString.new("").sub(//, "").should be_an_instance_of(StringSpecs::MyString)
|
||||
StringSpecs::MyString.new("").sub(/foo/, "").should be_an_instance_of(StringSpecs::MyString)
|
||||
StringSpecs::MyString.new("foo").sub(/foo/, "").should be_an_instance_of(StringSpecs::MyString)
|
||||
StringSpecs::MyString.new("foo").sub("foo", "").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("").sub(//, "").should be_an_instance_of(StringSpecs::MyString)
|
||||
StringSpecs::MyString.new("").sub(/foo/, "").should be_an_instance_of(StringSpecs::MyString)
|
||||
StringSpecs::MyString.new("foo").sub(/foo/, "").should be_an_instance_of(StringSpecs::MyString)
|
||||
StringSpecs::MyString.new("foo").sub("foo", "").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("").sub(//, "").should be_an_instance_of(String)
|
||||
StringSpecs::MyString.new("").sub(/foo/, "").should be_an_instance_of(String)
|
||||
StringSpecs::MyString.new("foo").sub(/foo/, "").should be_an_instance_of(String)
|
||||
StringSpecs::MyString.new("foo").sub("foo", "").should be_an_instance_of(String)
|
||||
end
|
||||
end
|
||||
|
||||
it "sets $~ to MatchData of match and nil when there's none" do
|
||||
|
|
|
@ -73,9 +73,18 @@ describe "String#swapcase" do
|
|||
-> { "abc".swapcase(:invalid_option) }.should raise_error(ArgumentError)
|
||||
end
|
||||
|
||||
it "returns subclass instances when called on a subclass" do
|
||||
StringSpecs::MyString.new("").swapcase.should be_an_instance_of(StringSpecs::MyString)
|
||||
StringSpecs::MyString.new("hello").swapcase.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("").swapcase.should be_an_instance_of(StringSpecs::MyString)
|
||||
StringSpecs::MyString.new("hello").swapcase.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("").swapcase.should be_an_instance_of(String)
|
||||
StringSpecs::MyString.new("hello").swapcase.should be_an_instance_of(String)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -45,8 +45,16 @@ describe "String#tr_s" do
|
|||
"bla".tr_s(from_str, to_str).should == "BlA"
|
||||
end
|
||||
|
||||
it "returns subclass instances when called on a subclass" do
|
||||
StringSpecs::MyString.new("hello").tr_s("e", "a").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").tr_s("e", "a").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").tr_s("e", "a").should be_an_instance_of(String)
|
||||
end
|
||||
end
|
||||
|
||||
ruby_version_is ''...'2.7' do
|
||||
|
|
|
@ -57,8 +57,16 @@ describe "String#tr" do
|
|||
"bla".tr(from_str, to_str).should == "BlA"
|
||||
end
|
||||
|
||||
it "returns subclass instances when called on a subclass" do
|
||||
StringSpecs::MyString.new("hello").tr("e", "a").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").tr("e", "a").should be_an_instance_of(StringSpecs::MyString)
|
||||
end
|
||||
end
|
||||
|
||||
ruby_version_is '3.0' do
|
||||
it "returns Stringinstances when called on a subclass" do
|
||||
StringSpecs::MyString.new("hello").tr("e", "a").should be_an_instance_of(String)
|
||||
end
|
||||
end
|
||||
|
||||
ruby_version_is ''...'2.7' do
|
||||
|
|
|
@ -73,8 +73,16 @@ describe "String#upcase" do
|
|||
end
|
||||
end
|
||||
|
||||
it "returns a subclass instance for subclasses" do
|
||||
StringSpecs::MyString.new("fooBAR").upcase.should be_an_instance_of(StringSpecs::MyString)
|
||||
ruby_version_is ''...'3.0' do
|
||||
it "returns a subclass instance for subclasses" do
|
||||
StringSpecs::MyString.new("fooBAR").upcase.should be_an_instance_of(StringSpecs::MyString)
|
||||
end
|
||||
end
|
||||
|
||||
ruby_version_is '3.0' do
|
||||
it "returns a String instance for subclasses" do
|
||||
StringSpecs::MyString.new("fooBAR").upcase.should be_an_instance_of(String)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -32,10 +32,20 @@ describe :string_times, shared: true do
|
|||
@object.call("", max_long).should == ""
|
||||
end
|
||||
|
||||
it "returns subclass instances" do
|
||||
@object.call(MyString.new("cool"), 0).should be_an_instance_of(MyString)
|
||||
@object.call(MyString.new("cool"), 1).should be_an_instance_of(MyString)
|
||||
@object.call(MyString.new("cool"), 2).should be_an_instance_of(MyString)
|
||||
ruby_version_is ''...'3.0' do
|
||||
it "returns subclass instances" do
|
||||
@object.call(MyString.new("cool"), 0).should be_an_instance_of(MyString)
|
||||
@object.call(MyString.new("cool"), 1).should be_an_instance_of(MyString)
|
||||
@object.call(MyString.new("cool"), 2).should be_an_instance_of(MyString)
|
||||
end
|
||||
end
|
||||
|
||||
ruby_version_is '3.0' do
|
||||
it "returns String instances" do
|
||||
@object.call(MyString.new("cool"), 0).should be_an_instance_of(String)
|
||||
@object.call(MyString.new("cool"), 1).should be_an_instance_of(String)
|
||||
@object.call(MyString.new("cool"), 2).should be_an_instance_of(String)
|
||||
end
|
||||
end
|
||||
|
||||
ruby_version_is ''...'2.7' do
|
||||
|
|
122
string.c
122
string.c
|
@ -1228,6 +1228,13 @@ rb_str_new_frozen(VALUE orig)
|
|||
return str_new_frozen(rb_obj_class(orig), orig);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_str_new_frozen_String(VALUE orig)
|
||||
{
|
||||
if (OBJ_FROZEN(orig) && rb_obj_class(orig) == rb_cString) return orig;
|
||||
return str_new_frozen(rb_cString, orig);
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_str_tmp_frozen_acquire(VALUE orig)
|
||||
{
|
||||
|
@ -1336,6 +1343,14 @@ str_new_empty(VALUE str)
|
|||
return v;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
str_new_empty_String(VALUE str)
|
||||
{
|
||||
VALUE v = rb_str_new(0, 0);
|
||||
rb_enc_copy(v, str);
|
||||
return v;
|
||||
}
|
||||
|
||||
#define STR_BUF_MIN_SIZE 63
|
||||
STATIC_ASSERT(STR_BUF_MIN_SIZE, STR_BUF_MIN_SIZE > RSTRING_EMBED_LEN_MAX);
|
||||
|
||||
|
@ -2036,10 +2051,10 @@ rb_str_times(VALUE str, VALUE times)
|
|||
int termlen;
|
||||
|
||||
if (times == INT2FIX(1)) {
|
||||
return rb_str_dup(str);
|
||||
return str_duplicate(rb_cString, str);
|
||||
}
|
||||
if (times == INT2FIX(0)) {
|
||||
str2 = str_alloc(rb_obj_class(str));
|
||||
str2 = str_alloc(rb_cString);
|
||||
rb_enc_copy(str2, str);
|
||||
return str2;
|
||||
}
|
||||
|
@ -2048,7 +2063,7 @@ rb_str_times(VALUE str, VALUE times)
|
|||
rb_raise(rb_eArgError, "negative argument");
|
||||
}
|
||||
if (RSTRING_LEN(str) == 1 && RSTRING_PTR(str)[0] == 0) {
|
||||
str2 = str_alloc(rb_obj_class(str));
|
||||
str2 = str_alloc(rb_cString);
|
||||
if (!STR_EMBEDDABLE_P(len, 1)) {
|
||||
RSTRING(str2)->as.heap.aux.capa = len;
|
||||
RSTRING(str2)->as.heap.ptr = ZALLOC_N(char, (size_t)len + 1);
|
||||
|
@ -2064,7 +2079,7 @@ rb_str_times(VALUE str, VALUE times)
|
|||
|
||||
len *= RSTRING_LEN(str);
|
||||
termlen = TERM_LEN(str);
|
||||
str2 = str_new0(rb_obj_class(str), 0, len, termlen);
|
||||
str2 = str_new0(rb_cString, 0, len, termlen);
|
||||
ptr2 = RSTRING_PTR(str2);
|
||||
if (len) {
|
||||
n = RSTRING_LEN(str);
|
||||
|
@ -2545,13 +2560,13 @@ rb_str_subseq(VALUE str, long beg, long len)
|
|||
if (!STR_EMBEDDABLE_P(len, TERM_LEN(str)) &&
|
||||
SHARABLE_SUBSTRING_P(beg, len, RSTRING_LEN(str))) {
|
||||
long olen;
|
||||
str2 = rb_str_new_shared(rb_str_new_frozen(str));
|
||||
str2 = rb_str_new_shared(rb_str_new_frozen_String(str));
|
||||
RSTRING(str2)->as.heap.ptr += beg;
|
||||
olen = RSTRING(str2)->as.heap.len;
|
||||
if (olen > len) RSTRING(str2)->as.heap.len = len;
|
||||
}
|
||||
else {
|
||||
str2 = rb_str_new_with_class(str, RSTRING_PTR(str)+beg, len);
|
||||
str2 = rb_str_new(RSTRING_PTR(str)+beg, len);
|
||||
RB_GC_GUARD(str);
|
||||
}
|
||||
|
||||
|
@ -2664,14 +2679,14 @@ str_substr(VALUE str, long beg, long len, int empty)
|
|||
SHARABLE_SUBSTRING_P(p, len, RSTRING_END(str))) {
|
||||
long ofs = p - RSTRING_PTR(str);
|
||||
str2 = rb_str_new_frozen(str);
|
||||
str2 = str_new_shared(rb_obj_class(str2), str2);
|
||||
str2 = str_new_shared(rb_cString, str2);
|
||||
RSTRING(str2)->as.heap.ptr += ofs;
|
||||
RSTRING(str2)->as.heap.len = len;
|
||||
ENC_CODERANGE_CLEAR(str2);
|
||||
}
|
||||
else {
|
||||
if (!len && !empty) return Qnil;
|
||||
str2 = rb_str_new_with_class(str, p, len);
|
||||
str2 = rb_str_new(p, len);
|
||||
RB_GC_GUARD(str);
|
||||
}
|
||||
rb_enc_cr_str_copy_for_substr(str2, str);
|
||||
|
@ -4215,7 +4230,7 @@ VALUE
|
|||
rb_str_succ(VALUE orig)
|
||||
{
|
||||
VALUE str;
|
||||
str = rb_str_new_with_class(orig, RSTRING_PTR(orig), RSTRING_LEN(orig));
|
||||
str = rb_str_new(RSTRING_PTR(orig), RSTRING_LEN(orig));
|
||||
rb_enc_cr_str_copy_for_substr(str, orig);
|
||||
return str_succ(str);
|
||||
}
|
||||
|
@ -4444,7 +4459,7 @@ rb_str_upto_each(VALUE beg, VALUE end, int excl, int (*each)(VALUE, VALUE), VALU
|
|||
if (n > 0 || (excl && n == 0)) return beg;
|
||||
|
||||
after_end = rb_funcallv(end, succ, 0, 0);
|
||||
current = rb_str_dup(beg);
|
||||
current = str_duplicate(rb_cString, beg);
|
||||
while (!rb_str_equal(current, after_end)) {
|
||||
VALUE next = Qnil;
|
||||
if (excl || !rb_str_equal(current, end))
|
||||
|
@ -4492,7 +4507,7 @@ rb_str_upto_endless_each(VALUE beg, int (*each)(VALUE, VALUE), VALUE arg)
|
|||
}
|
||||
}
|
||||
/* normal case */
|
||||
current = rb_str_dup(beg);
|
||||
current = str_duplicate(rb_cString, beg);
|
||||
while (1) {
|
||||
VALUE next = rb_funcallv(current, succ, 0, 0);
|
||||
if ((*each)(current, arg)) break;
|
||||
|
@ -4582,7 +4597,7 @@ rb_str_aref(VALUE str, VALUE indx)
|
|||
}
|
||||
else if (RB_TYPE_P(indx, T_STRING)) {
|
||||
if (rb_str_index(str, indx, 0) != -1)
|
||||
return rb_str_dup(indx);
|
||||
return str_duplicate(rb_cString, indx);
|
||||
return Qnil;
|
||||
}
|
||||
else {
|
||||
|
@ -5005,7 +5020,7 @@ rb_str_slice_bang(int argc, VALUE *argv, VALUE str)
|
|||
beg = rb_str_index(str, indx, 0);
|
||||
if (beg == -1) return Qnil;
|
||||
len = RSTRING_LEN(indx);
|
||||
result = rb_str_dup(indx);
|
||||
result = str_duplicate(rb_cString, indx);
|
||||
goto squash;
|
||||
}
|
||||
else {
|
||||
|
@ -5028,7 +5043,7 @@ rb_str_slice_bang(int argc, VALUE *argv, VALUE str)
|
|||
beg = p - RSTRING_PTR(str);
|
||||
|
||||
subseq:
|
||||
result = rb_str_new_with_class(str, RSTRING_PTR(str)+beg, len);
|
||||
result = rb_str_new(RSTRING_PTR(str)+beg, len);
|
||||
rb_enc_cr_str_copy_for_substr(result, str);
|
||||
|
||||
squash:
|
||||
|
@ -5107,7 +5122,7 @@ rb_pat_search(VALUE pat, VALUE str, long pos, int set_backref_str)
|
|||
pos = rb_strseq_index(str, pat, pos, 1);
|
||||
if (set_backref_str) {
|
||||
if (pos >= 0) {
|
||||
str = rb_str_new_frozen(str);
|
||||
str = rb_str_new_frozen_String(str);
|
||||
rb_backref_set_string(str, pos, RSTRING_LEN(pat));
|
||||
}
|
||||
else {
|
||||
|
@ -5301,7 +5316,7 @@ rb_str_sub_bang(int argc, VALUE *argv, VALUE str)
|
|||
static VALUE
|
||||
rb_str_sub(int argc, VALUE *argv, VALUE str)
|
||||
{
|
||||
str = rb_str_dup(str);
|
||||
str = str_duplicate(rb_cString, str);
|
||||
rb_str_sub_bang(argc, argv, str);
|
||||
return str;
|
||||
}
|
||||
|
@ -5341,7 +5356,7 @@ str_gsub(int argc, VALUE *argv, VALUE str, int bang)
|
|||
beg = rb_pat_search(pat, str, 0, need_backref);
|
||||
if (beg < 0) {
|
||||
if (bang) return Qnil; /* no match, no substitution */
|
||||
return rb_str_dup(str);
|
||||
return str_duplicate(rb_cString, str);
|
||||
}
|
||||
|
||||
offset = 0;
|
||||
|
@ -5422,7 +5437,6 @@ str_gsub(int argc, VALUE *argv, VALUE str, int bang)
|
|||
str_shared_replace(str, dest);
|
||||
}
|
||||
else {
|
||||
RBASIC_SET_CLASS(dest, rb_obj_class(str));
|
||||
str = dest;
|
||||
}
|
||||
|
||||
|
@ -5685,12 +5699,12 @@ str_byte_substr(VALUE str, long beg, long len, int empty)
|
|||
|
||||
if (!STR_EMBEDDABLE_P(len, TERM_LEN(str)) && SHARABLE_SUBSTRING_P(beg, len, n)) {
|
||||
str2 = rb_str_new_frozen(str);
|
||||
str2 = str_new_shared(rb_obj_class(str2), str2);
|
||||
str2 = str_new_shared(rb_cString, str2);
|
||||
RSTRING(str2)->as.heap.ptr += beg;
|
||||
RSTRING(str2)->as.heap.len = len;
|
||||
}
|
||||
else {
|
||||
str2 = rb_str_new_with_class(str, p, len);
|
||||
str2 = rb_str_new(p, len);
|
||||
}
|
||||
|
||||
str_enc_copy(str2, str);
|
||||
|
@ -5792,9 +5806,9 @@ rb_str_reverse(VALUE str)
|
|||
char *s, *e, *p;
|
||||
int cr;
|
||||
|
||||
if (RSTRING_LEN(str) <= 1) return rb_str_dup(str);
|
||||
if (RSTRING_LEN(str) <= 1) return str_duplicate(rb_cString, str);
|
||||
enc = STR_ENC_GET(str);
|
||||
rev = rb_str_new_with_class(str, 0, RSTRING_LEN(str));
|
||||
rev = rb_str_new(0, RSTRING_LEN(str));
|
||||
s = RSTRING_PTR(str); e = RSTRING_END(str);
|
||||
p = RSTRING_END(rev);
|
||||
cr = ENC_CODERANGE(str);
|
||||
|
@ -6273,7 +6287,7 @@ rb_str_dump(VALUE str)
|
|||
len += clen;
|
||||
}
|
||||
|
||||
result = rb_str_new_with_class(str, 0, len);
|
||||
result = rb_str_new(0, len);
|
||||
p = RSTRING_PTR(str); pend = p + RSTRING_LEN(str);
|
||||
q = RSTRING_PTR(result); qend = q + len + 1;
|
||||
|
||||
|
@ -6696,7 +6710,7 @@ rb_str_casemap(VALUE source, OnigCaseFoldType *flags, rb_encoding *enc)
|
|||
size_t buffer_count = 0;
|
||||
int buffer_length_or_invalid;
|
||||
|
||||
if (RSTRING_LEN(source) == 0) return rb_str_dup(source);
|
||||
if (RSTRING_LEN(source) == 0) return str_duplicate(rb_cString, source);
|
||||
|
||||
source_current = (OnigUChar*)RSTRING_PTR(source);
|
||||
source_end = (OnigUChar*)RSTRING_END(source);
|
||||
|
@ -6732,12 +6746,12 @@ rb_str_casemap(VALUE source, OnigCaseFoldType *flags, rb_encoding *enc)
|
|||
}
|
||||
|
||||
if (buffer_count==1) {
|
||||
target = rb_str_new_with_class(source, (const char*)current_buffer->space, target_length);
|
||||
target = rb_str_new((const char*)current_buffer->space, target_length);
|
||||
}
|
||||
else {
|
||||
char *target_current;
|
||||
|
||||
target = rb_str_new_with_class(source, 0, target_length);
|
||||
target = rb_str_new(0, target_length);
|
||||
target_current = RSTRING_PTR(target);
|
||||
current_buffer = DATA_PTR(buffer_anchor);
|
||||
while (current_buffer) {
|
||||
|
@ -6870,12 +6884,12 @@ rb_str_upcase(int argc, VALUE *argv, VALUE str)
|
|||
flags = check_case_options(argc, argv, flags);
|
||||
enc = str_true_enc(str);
|
||||
if (case_option_single_p(flags, enc, str)) {
|
||||
ret = rb_str_new_with_class(str, RSTRING_PTR(str), RSTRING_LEN(str));
|
||||
ret = rb_str_new(RSTRING_PTR(str), RSTRING_LEN(str));
|
||||
str_enc_copy(ret, str);
|
||||
upcase_single(ret);
|
||||
}
|
||||
else if (flags&ONIGENC_CASE_ASCII_ONLY) {
|
||||
ret = rb_str_new_with_class(str, 0, RSTRING_LEN(str));
|
||||
ret = rb_str_new(0, RSTRING_LEN(str));
|
||||
rb_str_ascii_casemap(str, ret, &flags, enc);
|
||||
}
|
||||
else {
|
||||
|
@ -6998,12 +7012,12 @@ rb_str_downcase(int argc, VALUE *argv, VALUE str)
|
|||
flags = check_case_options(argc, argv, flags);
|
||||
enc = str_true_enc(str);
|
||||
if (case_option_single_p(flags, enc, str)) {
|
||||
ret = rb_str_new_with_class(str, RSTRING_PTR(str), RSTRING_LEN(str));
|
||||
ret = rb_str_new(RSTRING_PTR(str), RSTRING_LEN(str));
|
||||
str_enc_copy(ret, str);
|
||||
downcase_single(ret);
|
||||
}
|
||||
else if (flags&ONIGENC_CASE_ASCII_ONLY) {
|
||||
ret = rb_str_new_with_class(str, 0, RSTRING_LEN(str));
|
||||
ret = rb_str_new(0, RSTRING_LEN(str));
|
||||
rb_str_ascii_casemap(str, ret, &flags, enc);
|
||||
}
|
||||
else {
|
||||
|
@ -7078,7 +7092,7 @@ rb_str_capitalize(int argc, VALUE *argv, VALUE str)
|
|||
enc = str_true_enc(str);
|
||||
if (RSTRING_LEN(str) == 0 || !RSTRING_PTR(str)) return str;
|
||||
if (flags&ONIGENC_CASE_ASCII_ONLY) {
|
||||
ret = rb_str_new_with_class(str, 0, RSTRING_LEN(str));
|
||||
ret = rb_str_new(0, RSTRING_LEN(str));
|
||||
rb_str_ascii_casemap(str, ret, &flags, enc);
|
||||
}
|
||||
else {
|
||||
|
@ -7142,9 +7156,9 @@ rb_str_swapcase(int argc, VALUE *argv, VALUE str)
|
|||
|
||||
flags = check_case_options(argc, argv, flags);
|
||||
enc = str_true_enc(str);
|
||||
if (RSTRING_LEN(str) == 0 || !RSTRING_PTR(str)) return str;
|
||||
if (RSTRING_LEN(str) == 0 || !RSTRING_PTR(str)) return str_duplicate(rb_cString, str);
|
||||
if (flags&ONIGENC_CASE_ASCII_ONLY) {
|
||||
ret = rb_str_new_with_class(str, 0, RSTRING_LEN(str));
|
||||
ret = rb_str_new(0, RSTRING_LEN(str));
|
||||
rb_str_ascii_casemap(str, ret, &flags, enc);
|
||||
}
|
||||
else {
|
||||
|
@ -7518,7 +7532,7 @@ rb_str_tr_bang(VALUE str, VALUE src, VALUE repl)
|
|||
static VALUE
|
||||
rb_str_tr(VALUE str, VALUE src, VALUE repl)
|
||||
{
|
||||
str = rb_str_dup(str);
|
||||
str = str_duplicate(rb_cString, str);
|
||||
tr_trans(str, src, repl, 0);
|
||||
return str;
|
||||
}
|
||||
|
@ -7697,7 +7711,7 @@ rb_str_delete_bang(int argc, VALUE *argv, VALUE str)
|
|||
static VALUE
|
||||
rb_str_delete(int argc, VALUE *argv, VALUE str)
|
||||
{
|
||||
str = rb_str_dup(str);
|
||||
str = str_duplicate(rb_cString, str);
|
||||
rb_str_delete_bang(argc, argv, str);
|
||||
return str;
|
||||
}
|
||||
|
@ -7805,7 +7819,7 @@ rb_str_squeeze_bang(int argc, VALUE *argv, VALUE str)
|
|||
static VALUE
|
||||
rb_str_squeeze(int argc, VALUE *argv, VALUE str)
|
||||
{
|
||||
str = rb_str_dup(str);
|
||||
str = str_duplicate(rb_cString, str);
|
||||
rb_str_squeeze_bang(argc, argv, str);
|
||||
return str;
|
||||
}
|
||||
|
@ -7842,7 +7856,7 @@ rb_str_tr_s_bang(VALUE str, VALUE src, VALUE repl)
|
|||
static VALUE
|
||||
rb_str_tr_s(VALUE str, VALUE src, VALUE repl)
|
||||
{
|
||||
str = rb_str_dup(str);
|
||||
str = str_duplicate(rb_cString, str);
|
||||
tr_trans(str, src, repl, 1);
|
||||
return str;
|
||||
}
|
||||
|
@ -7986,12 +8000,12 @@ split_string(VALUE result, VALUE str, long beg, long len, long empty_count)
|
|||
/* make different substrings */
|
||||
if (result) {
|
||||
do {
|
||||
rb_ary_push(result, str_new_empty(str));
|
||||
rb_ary_push(result, str_new_empty_String(str));
|
||||
} while (--empty_count > 0);
|
||||
}
|
||||
else {
|
||||
do {
|
||||
rb_yield(str_new_empty(str));
|
||||
rb_yield(str_new_empty_String(str));
|
||||
} while (--empty_count > 0);
|
||||
}
|
||||
}
|
||||
|
@ -8106,11 +8120,11 @@ rb_str_split_m(int argc, VALUE *argv, VALUE str)
|
|||
if (lim <= 0) limit = Qnil;
|
||||
else if (lim == 1) {
|
||||
if (RSTRING_LEN(str) == 0)
|
||||
return result ? rb_ary_new2(0) : str;
|
||||
tmp = rb_str_dup(str);
|
||||
return result ? rb_ary_new2(0) : str;
|
||||
tmp = str_duplicate(rb_cString, str);
|
||||
if (!result) {
|
||||
rb_yield(tmp);
|
||||
return str;
|
||||
return str;
|
||||
}
|
||||
return rb_ary_new3(1, tmp);
|
||||
}
|
||||
|
@ -9194,7 +9208,7 @@ static VALUE
|
|||
rb_str_chomp(int argc, VALUE *argv, VALUE str)
|
||||
{
|
||||
VALUE rs = chomp_rs(argc, argv);
|
||||
if (NIL_P(rs)) return rb_str_dup(str);
|
||||
if (NIL_P(rs)) return str_duplicate(rb_cString, str);
|
||||
return rb_str_subseq(str, 0, chompped_length(str, rs));
|
||||
}
|
||||
|
||||
|
@ -9281,7 +9295,7 @@ rb_str_lstrip(VALUE str)
|
|||
long len, loffset;
|
||||
RSTRING_GETMEM(str, start, len);
|
||||
loffset = lstrip_offset(str, start, start+len, STR_ENC_GET(str));
|
||||
if (loffset <= 0) return rb_str_dup(str);
|
||||
if (loffset <= 0) return str_duplicate(rb_cString, str);
|
||||
return rb_str_subseq(str, loffset, len - loffset);
|
||||
}
|
||||
|
||||
|
@ -9374,7 +9388,7 @@ rb_str_rstrip(VALUE str)
|
|||
RSTRING_GETMEM(str, start, olen);
|
||||
roffset = rstrip_offset(str, start, start+olen, enc);
|
||||
|
||||
if (roffset <= 0) return rb_str_dup(str);
|
||||
if (roffset <= 0) return str_duplicate(rb_cString, str);
|
||||
return rb_str_subseq(str, 0, olen-roffset);
|
||||
}
|
||||
|
||||
|
@ -9447,7 +9461,7 @@ rb_str_strip(VALUE str)
|
|||
loffset = lstrip_offset(str, start, start+olen, enc);
|
||||
roffset = rstrip_offset(str, start+loffset, start+olen, enc);
|
||||
|
||||
if (loffset <= 0 && roffset <= 0) return rb_str_dup(str);
|
||||
if (loffset <= 0 && roffset <= 0) return str_duplicate(rb_cString, str);
|
||||
return rb_str_subseq(str, loffset, olen-loffset-roffset);
|
||||
}
|
||||
|
||||
|
@ -9843,7 +9857,7 @@ rb_str_justify(int argc, VALUE *argv, VALUE str, char jflag)
|
|||
}
|
||||
}
|
||||
len = str_strlen(str, enc); /* rb_enc_check */
|
||||
if (width < 0 || len >= width) return rb_str_dup(str);
|
||||
if (width < 0 || len >= width) return str_duplicate(rb_cString, str);
|
||||
n = width - len;
|
||||
llen = (jflag == 'l') ? 0 : ((jflag == 'r') ? n : n/2);
|
||||
rlen = n - llen;
|
||||
|
@ -9859,7 +9873,7 @@ rb_str_justify(int argc, VALUE *argv, VALUE str, char jflag)
|
|||
rb_raise(rb_eArgError, "argument too big");
|
||||
}
|
||||
len += size;
|
||||
res = str_new0(rb_obj_class(str), 0, len, termlen);
|
||||
res = str_new0(rb_cString, 0, len, termlen);
|
||||
p = RSTRING_PTR(res);
|
||||
if (flen <= 1) {
|
||||
memset(p, *f, llen);
|
||||
|
@ -10006,7 +10020,7 @@ rb_str_partition(VALUE str, VALUE sep)
|
|||
RSTRING_LEN(str)-pos-RSTRING_LEN(sep)));
|
||||
|
||||
failed:
|
||||
return rb_ary_new3(3, rb_str_dup(str), str_new_empty(str), str_new_empty(str));
|
||||
return rb_ary_new3(3, str_duplicate(rb_cString, str), str_new_empty_String(str), str_new_empty_String(str));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -10054,7 +10068,7 @@ rb_str_rpartition(VALUE str, VALUE sep)
|
|||
rb_str_subseq(str, pos+RSTRING_LEN(sep),
|
||||
RSTRING_LEN(str)-pos-RSTRING_LEN(sep)));
|
||||
failed:
|
||||
return rb_ary_new3(3, str_new_empty(str), str_new_empty(str), rb_str_dup(str));
|
||||
return rb_ary_new3(3, str_new_empty_String(str), str_new_empty_String(str), str_duplicate(rb_cString, str));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -10200,7 +10214,7 @@ rb_str_delete_prefix(VALUE str, VALUE prefix)
|
|||
long prefixlen;
|
||||
|
||||
prefixlen = deleted_prefix_length(str, prefix);
|
||||
if (prefixlen <= 0) return rb_str_dup(str);
|
||||
if (prefixlen <= 0) return str_duplicate(rb_cString, str);
|
||||
|
||||
return rb_str_subseq(str, prefixlen, RSTRING_LEN(str) - prefixlen);
|
||||
}
|
||||
|
@ -10286,7 +10300,7 @@ rb_str_delete_suffix(VALUE str, VALUE suffix)
|
|||
long suffixlen;
|
||||
|
||||
suffixlen = deleted_suffix_length(str, suffix);
|
||||
if (suffixlen <= 0) return rb_str_dup(str);
|
||||
if (suffixlen <= 0) return str_duplicate(rb_cString, str);
|
||||
|
||||
return rb_str_subseq(str, 0, RSTRING_LEN(str) - suffixlen);
|
||||
}
|
||||
|
@ -10417,7 +10431,7 @@ rb_str_ellipsize(VALUE str, long len)
|
|||
else if (len <= ellipsislen ||
|
||||
!(e = rb_enc_step_back(p, e, e, len = ellipsislen, enc))) {
|
||||
if (rb_enc_asciicompat(enc)) {
|
||||
ret = rb_str_new_with_class(str, ellipsis, len);
|
||||
ret = rb_str_new(ellipsis, len);
|
||||
rb_enc_associate(ret, enc);
|
||||
}
|
||||
else {
|
||||
|
@ -10742,7 +10756,7 @@ str_scrub(int argc, VALUE *argv, VALUE str)
|
|||
{
|
||||
VALUE repl = argc ? (rb_check_arity(argc, 0, 1), argv[0]) : Qnil;
|
||||
VALUE new = rb_str_scrub(str, repl);
|
||||
return NIL_P(new) ? rb_str_dup(str): new;
|
||||
return NIL_P(new) ? str_duplicate(rb_cString, str): new;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -13,13 +13,13 @@ class Test_StringCStr < Test::Unit::TestCase
|
|||
end
|
||||
|
||||
def test_long
|
||||
s = Bug::String.new("abcdef")*100000
|
||||
s = Bug::String.new(Bug::String.new("abcdef")*100000)
|
||||
s.cstr_unterm('x')
|
||||
assert_equal(0, s.cstr_term, Bug4319)
|
||||
end
|
||||
|
||||
def test_shared
|
||||
s = Bug::String.new("abcdef")*5
|
||||
s = Bug::String.new(Bug::String.new("abcdef")*5)
|
||||
s = s.unterminated_substring(0, 29)
|
||||
assert_equal(0, s.cstr_term, Bug4319)
|
||||
end
|
||||
|
@ -28,7 +28,7 @@ class Test_StringCStr < Test::Unit::TestCase
|
|||
s0 = Bug::String.new("abcdefgh"*8)
|
||||
|
||||
[4, 4*3-1, 8*3-1, 64].each do |n|
|
||||
s = s0[0, n]
|
||||
s = Bug::String.new(s0[0, n])
|
||||
s.cstr_unterm('x')
|
||||
s.freeze
|
||||
assert_equal(0, s.cstr_term)
|
||||
|
@ -67,7 +67,7 @@ class Test_StringCStr < Test::Unit::TestCase
|
|||
n = 100
|
||||
len = str.size * n
|
||||
WCHARS.each do |enc|
|
||||
s = Bug::String.new(str.encode(enc))*n
|
||||
s = Bug::String.new(Bug::String.new(str.encode(enc))*n)
|
||||
s.cstr_unterm('x')
|
||||
assert_nothing_raised(ArgumentError, enc.name) {s.cstr_term}
|
||||
s.set_len(s.bytesize / 2)
|
||||
|
|
|
@ -10,7 +10,7 @@ class Test_StringEllipsize < Test::Unit::TestCase
|
|||
def assert_equal_with_class(expected, result, *rest)
|
||||
assert_equal(expected.encoding, result.encoding, *rest)
|
||||
assert_equal(expected, result, result.encoding.name)
|
||||
assert_instance_of(Bug::String, result, *rest)
|
||||
assert_instance_of(String, result, *rest)
|
||||
end
|
||||
|
||||
def test_longer
|
||||
|
|
|
@ -2089,6 +2089,8 @@ CODE
|
|||
|
||||
def test_swapcase
|
||||
assert_equal(S("hi&LOW"), S("HI&low").swapcase)
|
||||
s = S("")
|
||||
assert_not_same(s, s.swapcase)
|
||||
end
|
||||
|
||||
def test_swapcase!
|
||||
|
|
Загрузка…
Ссылка в новой задаче