diff options
Diffstat (limited to 'activesupport/lib/active_support/core_ext/hash')
4 files changed, 104 insertions, 23 deletions
diff --git a/activesupport/lib/active_support/core_ext/hash/conversions.rb b/activesupport/lib/active_support/core_ext/hash/conversions.rb index 469dc41f2d..7c72ead36c 100644 --- a/activesupport/lib/active_support/core_ext/hash/conversions.rb +++ b/activesupport/lib/active_support/core_ext/hash/conversions.rb @@ -57,8 +57,8 @@ class Hash # "TrueClass" => "boolean", # "FalseClass" => "boolean", # "Date" => "date", - # "DateTime" => "datetime", - # "Time" => "datetime" + # "DateTime" => "dateTime", + # "Time" => "dateTime" # } # # By default the root node is "hash", but that's configurable via the <tt>:root</tt> option. @@ -129,7 +129,7 @@ class Hash else xml_value = Hash[value.map { |k,v| [k, typecast_xml_value(v)] }] - # Turn { :files => { :file => #<StringIO> } into { :files => #<StringIO> } so it is compatible with + # Turn { :files => { :file => #<StringIO> } } into { :files => #<StringIO> } so it is compatible with # how multipart uploaded files from HTML appear xml_value['file'].is_a?(StringIO) ? xml_value['file'] : xml_value end diff --git a/activesupport/lib/active_support/core_ext/hash/except.rb b/activesupport/lib/active_support/core_ext/hash/except.rb index fafd4919b9..5a61906222 100644 --- a/activesupport/lib/active_support/core_ext/hash/except.rb +++ b/activesupport/lib/active_support/core_ext/hash/except.rb @@ -10,6 +10,7 @@ class Hash # # {:a => 1}.with_indifferent_access.except(:a) # => {} # {:a => 1}.with_indifferent_access.except('a') # => {} + # def except(*keys) dup.except!(*keys) end diff --git a/activesupport/lib/active_support/core_ext/hash/indifferent_access.rb b/activesupport/lib/active_support/core_ext/hash/indifferent_access.rb index c1f368d0eb..7d54c9fae6 100644 --- a/activesupport/lib/active_support/core_ext/hash/indifferent_access.rb +++ b/activesupport/lib/active_support/core_ext/hash/indifferent_access.rb @@ -5,6 +5,7 @@ class Hash # Returns an <tt>ActiveSupport::HashWithIndifferentAccess</tt> out of its receiver: # # {:a => 1}.with_indifferent_access["a"] # => 1 + # def with_indifferent_access ActiveSupport::HashWithIndifferentAccess.new_from_hash_copying_default(self) end @@ -18,5 +19,6 @@ class Hash # # b = {:b => 1} # {:a => b}.with_indifferent_access["a"] # calls b.nested_under_indifferent_access + # alias nested_under_indifferent_access with_indifferent_access end diff --git a/activesupport/lib/active_support/core_ext/hash/keys.rb b/activesupport/lib/active_support/core_ext/hash/keys.rb index be4d611ce7..8e728691c6 100644 --- a/activesupport/lib/active_support/core_ext/hash/keys.rb +++ b/activesupport/lib/active_support/core_ext/hash/keys.rb @@ -1,46 +1,59 @@ class Hash - # Return a new hash with all keys converted to strings. + # Return a new hash with all keys converted using the block operation. # - # { :name => 'Rob', :years => '28' }.stringify_keys - # #=> { "name" => "Rob", "years" => "28" } - def stringify_keys + # hash = { name: 'Rob', age: '28' } + # + # hash.transform_keys{ |key| key.to_s.upcase } + # # => { "NAME" => "Rob", "AGE" => "28" } + def transform_keys result = {} keys.each do |key| - result[key.to_s] = self[key] + result[yield(key)] = self[key] end result end - # Destructively convert all keys to strings. Same as - # +stringify_keys+, but modifies +self+. - def stringify_keys! + # Destructively convert all keys using the block operations. + # Same as transform_keys but modifies +self+ + def transform_keys! keys.each do |key| - self[key.to_s] = delete(key) + self[yield(key)] = delete(key) end self end + # Return a new hash with all keys converted to strings. + # + # hash = { name: 'Rob', age: '28' } + # + # hash.stringify_keys + # #=> { "name" => "Rob", "age" => "28" } + def stringify_keys + transform_keys{ |key| key.to_s } + end + + # Destructively convert all keys to strings. Same as + # +stringify_keys+, but modifies +self+. + def stringify_keys! + transform_keys!{ |key| key.to_s } + end + # Return a new hash with all keys converted to symbols, as long as # they respond to +to_sym+. # - # { 'name' => 'Rob', 'years' => '28' }.symbolize_keys - # #=> { :name => "Rob", :years => "28" } + # hash = { 'name' => 'Rob', 'age' => '28' } + # + # hash.symbolize_keys + # #=> { name: "Rob", age: "28" } def symbolize_keys - result = {} - keys.each do |key| - result[(key.to_sym rescue key)] = self[key] - end - result + transform_keys{ |key| key.to_sym rescue key } end alias_method :to_options, :symbolize_keys # Destructively convert all keys to symbols, as long as they respond # to +to_sym+. Same as +symbolize_keys+, but modifies +self+. def symbolize_keys! - keys.each do |key| - self[(key.to_sym rescue key)] = delete(key) - end - self + transform_keys!{ |key| key.to_sym rescue key } end alias_method :to_options!, :symbolize_keys! @@ -57,4 +70,69 @@ class Hash raise ArgumentError.new("Unknown key: #{k}") unless valid_keys.include?(k) end end + + # Return a new hash with all keys converted by the block operation. + # This includes the keys from the root hash and from all + # nested hashes. + # + # hash = { person: { name: 'Rob', age: '28' } } + # + # hash.deep_transform_keys{ |key| key.to_s.upcase } + # # => { "PERSON" => { "NAME" => "Rob", "AGE" => "28" } } + def deep_transform_keys(&block) + result = {} + each do |key, value| + result[yield(key)] = value.is_a?(Hash) ? value.deep_transform_keys(&block) : value + end + result + end + + # Destructively convert all keys by using the block operation. + # This includes the keys from the root hash and from all + # nested hashes. + def deep_transform_keys!(&block) + keys.each do |key| + value = delete(key) + self[yield(key)] = value.is_a?(Hash) ? value.deep_transform_keys!(&block) : value + end + self + end + + # Return a new hash with all keys converted to strings. + # This includes the keys from the root hash and from all + # nested hashes. + # + # hash = { person: { name: 'Rob', age: '28' } } + # + # hash.deep_stringify_keys + # # => { "person" => { "name" => "Rob", "age" => "28" } } + def deep_stringify_keys + deep_transform_keys{ |key| key.to_s } + end + + # Destructively convert all keys to strings. + # This includes the keys from the root hash and from all + # nested hashes. + def deep_stringify_keys! + deep_transform_keys!{ |key| key.to_s } + end + + # Return a new hash with all keys converted to symbols, as long as + # they respond to +to_sym+. This includes the keys from the root hash + # and from all nested hashes. + # + # hash = { 'person' => { 'name' => 'Rob', 'age' => '28' } } + # + # hash.deep_symbolize_keys + # # => { person: { name: "Rob", age: "28" } } + def deep_symbolize_keys + deep_transform_keys{ |key| key.to_sym rescue key } + end + + # Destructively convert all keys to symbols, as long as they respond + # to +to_sym+. This includes the keys from the root hash and from all + # nested hashes. + def deep_symbolize_keys! + deep_transform_keys!{ |key| key.to_sym rescue key } + end end |