aboutsummaryrefslogtreecommitdiffstats
path: root/activesupport/lib/active_support/core_ext/hash
diff options
context:
space:
mode:
Diffstat (limited to 'activesupport/lib/active_support/core_ext/hash')
-rw-r--r--activesupport/lib/active_support/core_ext/hash/conversions.rb6
-rw-r--r--activesupport/lib/active_support/core_ext/hash/except.rb1
-rw-r--r--activesupport/lib/active_support/core_ext/hash/indifferent_access.rb2
-rw-r--r--activesupport/lib/active_support/core_ext/hash/keys.rb118
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