diff --git a/activesupport/CHANGELOG b/activesupport/CHANGELOG index 468285ec43..d1ad138f50 100644 --- a/activesupport/CHANGELOG +++ b/activesupport/CHANGELOG @@ -1,5 +1,7 @@ *SVN* +* Add String#squish and String#squish! to remove consecutive chunks of whitespace. #11123 [jordi, Henrik N] + * Serialize BigDecimals as Floats when using to_yaml. #8746 [ernesto.jimenez] * Adding TimeWithZone #to_yaml, #to_datetime, #eql? and method aliases for duck-typing compatibility with Time [Geoff Buesing] diff --git a/activesupport/lib/active_support/core_ext/string.rb b/activesupport/lib/active_support/core_ext/string.rb index 5497b6f6f6..a83474f278 100644 --- a/activesupport/lib/active_support/core_ext/string.rb +++ b/activesupport/lib/active_support/core_ext/string.rb @@ -5,10 +5,12 @@ require 'active_support/core_ext/string/starts_ends_with' require 'active_support/core_ext/string/iterators' unless 'test'.respond_to?(:each_char) require 'active_support/core_ext/string/unicode' require 'active_support/core_ext/string/xchar' +require 'active_support/core_ext/string/filters' class String #:nodoc: include ActiveSupport::CoreExtensions::String::Access include ActiveSupport::CoreExtensions::String::Conversions + include ActiveSupport::CoreExtensions::String::Filters include ActiveSupport::CoreExtensions::String::Inflections if RUBY_VERSION < '1.9' include ActiveSupport::CoreExtensions::String::StartsEndsWith diff --git a/activesupport/lib/active_support/core_ext/string/filters.rb b/activesupport/lib/active_support/core_ext/string/filters.rb new file mode 100644 index 0000000000..3a69131ea0 --- /dev/null +++ b/activesupport/lib/active_support/core_ext/string/filters.rb @@ -0,0 +1,24 @@ +module ActiveSupport #:nodoc: + module CoreExtensions #:nodoc: + module String #:nodoc: + module Filters + # Returns the string, first removing all whitespace on both ends of + # the string, and then changing remaining consecutive whitespace + # groups into one space each. + # + # Examples: + # %{ Multi-line + # string }.squish # => "Multi-line string" + # " foo bar \n \t boo".squish # => "foo bar boo" + def squish + strip.gsub(/\s+/, ' ') + end + + # Performs a destructive squish. See String#squish. + def squish! + replace(squish) + end + end + end + end +end diff --git a/activesupport/test/core_ext/string_ext_test.rb b/activesupport/test/core_ext/string_ext_test.rb index e1525d6170..19a30f1730 100644 --- a/activesupport/test/core_ext/string_ext_test.rb +++ b/activesupport/test/core_ext/string_ext_test.rb @@ -168,6 +168,23 @@ class StringInflectionsTest < Test::Unit::TestCase assert !s.end_with?('el') end + def test_string_squish + original = %{ A string with tabs(\t\t), newlines(\n\n), and + many spaces( ). } + + expected = "A string with tabs( ), newlines( ), and many spaces( )." + + # Make sure squish returns what we expect: + assert_equal original.squish, expected + # But doesn't modify the original string: + assert_not_equal original, expected + + # Make sure squish! returns what we expect: + assert_equal original.squish!, expected + # And changes the original string: + assert_equal original, expected + end + if RUBY_VERSION < '1.9' def test_each_char_with_utf8_string_when_kcode_is_utf8 old_kcode, $KCODE = $KCODE, 'UTF8'