diff --git a/spec/std/string_spec.cr b/spec/std/string_spec.cr index 6d7487ded0e2..e33ee67cd0f4 100644 --- a/spec/std/string_spec.cr +++ b/spec/std/string_spec.cr @@ -773,6 +773,24 @@ describe "String" do it { "hello\n\n\n\n".chomp("").should eq("hello\n\n\n\n") } it { "hello\r\n".chomp("\n").should eq("hello") } + + it "pre-computes string size if possible" do + {"!hello!", "\u{1f602}hello\u{1f602}", "\xFEhello\xFF"}.each do |str| + {"", "\n", "\r", "\r\n"}.each do |newline| + x = str + newline + x.size # side-effect + y = x.chomp + y.@length.should eq(7) + end + end + end + + it "does not pre-compute string size if not possible" do + x = String.build &.<< "abc\n" + x.@length.should eq(0) + y = x.chomp + y.@length.should eq(0) + end end describe "lchop" do diff --git a/src/string.cr b/src/string.cr index 7507e3b7249e..09272c80eb45 100644 --- a/src/string.cr +++ b/src/string.cr @@ -1661,12 +1661,12 @@ class String case to_unsafe[bytesize - 1] when '\n' if bytesize > 1 && to_unsafe[bytesize - 2] === '\r' - unsafe_byte_slice_string(0, bytesize - 2) + unsafe_byte_slice_string(0, bytesize - 2, @length > 0 ? @length - 2 : 0) else - unsafe_byte_slice_string(0, bytesize - 1) + unsafe_byte_slice_string(0, bytesize - 1, @length > 0 ? @length - 1 : 0) end when '\r' - unsafe_byte_slice_string(0, bytesize - 1) + unsafe_byte_slice_string(0, bytesize - 1, @length > 0 ? @length - 1 : 0) else self end @@ -5552,12 +5552,12 @@ class String Slice.new(to_unsafe + byte_offset, bytesize - byte_offset, read_only: true) end - protected def unsafe_byte_slice_string(byte_offset) - String.new(unsafe_byte_slice(byte_offset)) + protected def unsafe_byte_slice_string(byte_offset, *, size = 0) + String.new(to_unsafe + byte_offset, bytesize - byte_offset, size) end - protected def unsafe_byte_slice_string(byte_offset, count) - String.new(unsafe_byte_slice(byte_offset, count)) + protected def unsafe_byte_slice_string(byte_offset, count, size = 0) + String.new(to_unsafe + byte_offset, count, size) end protected def self.char_bytes_and_bytesize(char : Char)