diff options
author | Ernie Miller <ernie@erniemiller.org> | 2014-04-18 14:55:30 -0400 |
---|---|---|
committer | Ernie Miller <ernie@erniemiller.org> | 2014-04-18 14:55:30 -0400 |
commit | 9e67954dcfdc92f1087a03c0b1c61251d993e270 (patch) | |
tree | 3e9e799de5bbbf39c4ea506040e7912e590cdac3 /activesupport | |
parent | 99352088ca9629147150627b2702684f9bf1e608 (diff) | |
download | rails-9e67954dcfdc92f1087a03c0b1c61251d993e270.tar.gz rails-9e67954dcfdc92f1087a03c0b1c61251d993e270.tar.bz2 rails-9e67954dcfdc92f1087a03c0b1c61251d993e270.zip |
Fix inconsistent behavior from String#first/#last
While calling String#first or String#last with zero or a Fixnum < the
string's length returns a new string, a Fixnum >= the string's length
returns the string itself. This inconsistency can lead to inadvertent
mutation of a string.
Diffstat (limited to 'activesupport')
-rw-r--r-- | activesupport/lib/active_support/core_ext/string/access.rb | 8 | ||||
-rw-r--r-- | activesupport/test/core_ext/string_ext_test.rb | 12 |
2 files changed, 16 insertions, 4 deletions
diff --git a/activesupport/lib/active_support/core_ext/string/access.rb b/activesupport/lib/active_support/core_ext/string/access.rb index 6018fd9641..ebd0dd3fc7 100644 --- a/activesupport/lib/active_support/core_ext/string/access.rb +++ b/activesupport/lib/active_support/core_ext/string/access.rb @@ -64,7 +64,7 @@ class String # Returns the first character. If a limit is supplied, returns a substring # from the beginning of the string until it reaches the limit value. If the - # given limit is greater than or equal to the string length, returns self. + # given limit is greater than or equal to the string length, returns a copy of self. # # str = "hello" # str.first # => "h" @@ -76,7 +76,7 @@ class String if limit == 0 '' elsif limit >= size - self + self.dup else to(limit - 1) end @@ -84,7 +84,7 @@ class String # Returns the last character of the string. If a limit is supplied, returns a substring # from the end of the string until it reaches the limit value (counting backwards). If - # the given limit is greater than or equal to the string length, returns self. + # the given limit is greater than or equal to the string length, returns a copy of self. # # str = "hello" # str.last # => "o" @@ -96,7 +96,7 @@ class String if limit == 0 '' elsif limit >= size - self + self.dup else from(-limit) end diff --git a/activesupport/test/core_ext/string_ext_test.rb b/activesupport/test/core_ext/string_ext_test.rb index ea12f1ced5..f8d4d0f0dc 100644 --- a/activesupport/test/core_ext/string_ext_test.rb +++ b/activesupport/test/core_ext/string_ext_test.rb @@ -296,6 +296,12 @@ class StringAccessTest < ActiveSupport::TestCase assert_equal 'x', 'x'.first(4) end + test "#first with Fixnum >= string length still returns a new string" do + string = "hello" + different_string = string.first(5) + assert_not_same different_string, string + end + test "#last returns the last character" do assert_equal "o", "hello".last assert_equal 'x', 'x'.last @@ -308,6 +314,12 @@ class StringAccessTest < ActiveSupport::TestCase assert_equal 'x', 'x'.last(4) end + test "#last with Fixnum >= string length still returns a new string" do + string = "hello" + different_string = string.last(5) + assert_not_same different_string, string + end + test "access returns a real string" do hash = {} hash["h"] = true |