Skip to content

Commit

Permalink
Added Hash#reverse_merge, Hash#reverse_merge!, and Hash#reverse_updat…
Browse files Browse the repository at this point in the history
…e to ease the use of default options. Added :connector and :skip_last_comma options to Array#to_sentence

git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@2192 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
  • Loading branch information
dhh committed Sep 11, 2005
1 parent c100737 commit 8ae68ef
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 7 deletions.
2 changes: 2 additions & 0 deletions activesupport/CHANGELOG
@@ -1,5 +1,7 @@
*SVN* *SVN*


* Added Hash#reverse_merge, Hash#reverse_merge!, and Hash#reverse_update to ease the use of default options

* Added Array#to_sentence that'll turn ['one', 'two', 'three'] into "one, two, and three" #2157 [m.stienstra@fngtps.com] * Added Array#to_sentence that'll turn ['one', 'two', 'three'] into "one, two, and three" #2157 [m.stienstra@fngtps.com]


* Added Kernel#silence_warnings to turn off warnings temporarily for the passed block * Added Kernel#silence_warnings to turn off warnings temporarily for the passed block
Expand Down
20 changes: 14 additions & 6 deletions activesupport/lib/active_support/core_ext/array/conversions.rb
Expand Up @@ -3,12 +3,20 @@ module CoreExtensions #:nodoc:
module Array #:nodoc: module Array #:nodoc:
# Enables to conversion of Arrays to human readable lists. ['one', 'two', 'three'] => "one, two, and three" # Enables to conversion of Arrays to human readable lists. ['one', 'two', 'three'] => "one, two, and three"
module Conversions module Conversions
# Converts the array to comma-seperated sentence where the last element is joined by the connector word (default is 'and'). # Converts the array to comma-seperated sentence where the last element is joined by the connector word. Options:
def to_sentence(connector = 'and') # * <tt>:connector</tt>: The word used to join the last element in arrays with more than two elements (default: "and")
if length > 1 # * <tt>:skip_last_comma</tt>: Set to true to return "a, b and c" instead of "a, b, and c".
"#{self[0...-1].join(', ')}, #{connector} #{self[-1]}" def to_sentence(options = {})
elsif length == 1 options.assert_valid_keys(:connector, :skip_last_comma)
self[0] options.reverse_merge! :connector => 'and', :skip_last_comma => false

case length
when 1
self[0]
when 2
"#{self[0]} #{options[:connector]} #{self[1]}"
else
"#{self[0...-1].join(', ')}#{options[:skip_last_comma] ? '' : ','} #{options[:connector]} #{self[-1]}"
end end
end end


Expand Down
2 changes: 2 additions & 0 deletions activesupport/lib/active_support/core_ext/hash.rb
@@ -1,7 +1,9 @@
require File.dirname(__FILE__) + '/hash/keys' require File.dirname(__FILE__) + '/hash/keys'
require File.dirname(__FILE__) + '/hash/indifferent_access' require File.dirname(__FILE__) + '/hash/indifferent_access'
require File.dirname(__FILE__) + '/hash/reverse_merge'


class Hash #:nodoc: class Hash #:nodoc:
include ActiveSupport::CoreExtensions::Hash::Keys include ActiveSupport::CoreExtensions::Hash::Keys
include ActiveSupport::CoreExtensions::Hash::IndifferentAccess include ActiveSupport::CoreExtensions::Hash::IndifferentAccess
include ActiveSupport::CoreExtensions::Hash::ReverseMerge
end end
25 changes: 25 additions & 0 deletions activesupport/lib/active_support/core_ext/hash/reverse_merge.rb
@@ -0,0 +1,25 @@
module ActiveSupport #:nodoc:
module CoreExtensions #:nodoc:
module Hash #:nodoc:
# Allows for reverse merging where its the keys in the calling hash that wins over those in the <tt>other_hash</tt>.
# This is particularly useful for initializing an incoming option hash with default values:
#
# def setup(options = {})
# options.reverse_merge! :size => 25, :velocity => 10
# end
#
# The default :size and :velocity is only set if the +options+ passed in doesn't already have those keys set.
module ReverseMerge
def reverse_merge(other_hash)
other_hash.merge(self)
end

def reverse_merge!(other_hash)
replace(reverse_merge(other_hash))
end

alias_method :reverse_update, :reverse_merge
end
end
end
end
10 changes: 9 additions & 1 deletion activesupport/test/core_ext/array_ext_test.rb
Expand Up @@ -19,7 +19,15 @@ def test_plain_array_to_sentence
end end


def test_to_sentence_with_connector def test_to_sentence_with_connector
assert_equal "one, two, and also three", ['one', 'two', 'three'].to_sentence('and also') assert_equal "one, two, and also three", ['one', 'two', 'three'].to_sentence(:connector => 'and also')
end

def test_to_sentence_with_skip_last_comma
assert_equal "one, two and three", ['one', 'two', 'three'].to_sentence(:skip_last_comma => true)
end

def test_two_elements
assert_equal "one and two", ['one', 'two'].to_sentence
end end


def test_one_element def test_one_element
Expand Down
4 changes: 4 additions & 0 deletions activesupport/test/core_ext/hash_ext_test.rb
Expand Up @@ -118,4 +118,8 @@ def test_assorted_keys_not_stringified
indiff = original.with_indifferent_access indiff = original.with_indifferent_access
assert(!indiff.keys.any? {|k| k.kind_of? String}, "A key was converted to a string!") assert(!indiff.keys.any? {|k| k.kind_of? String}, "A key was converted to a string!")
end end

def test_reverse_merge
assert_equal({ :a => 1, :b => 2, :c => 10 }, { :a => 1, :b => 2 }.reverse_merge({:a => "x", :b => "y", :c => 10}) )
end
end end

0 comments on commit 8ae68ef

Please sign in to comment.