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/compact.rb2
-rw-r--r--activesupport/lib/active_support/core_ext/hash/deep_transform_values.rb46
-rw-r--r--activesupport/lib/active_support/core_ext/hash/except.rb2
-rw-r--r--activesupport/lib/active_support/core_ext/hash/keys.rb29
-rw-r--r--activesupport/lib/active_support/core_ext/hash/slice.rb23
-rw-r--r--activesupport/lib/active_support/core_ext/hash/transform_values.rb2
6 files changed, 49 insertions, 55 deletions
diff --git a/activesupport/lib/active_support/core_ext/hash/compact.rb b/activesupport/lib/active_support/core_ext/hash/compact.rb
index 28c8d86b9b..5cb858af5c 100644
--- a/activesupport/lib/active_support/core_ext/hash/compact.rb
+++ b/activesupport/lib/active_support/core_ext/hash/compact.rb
@@ -2,4 +2,4 @@
require "active_support/deprecation"
-ActiveSupport::Deprecation.warn "Ruby 2.4+ (required by Rails 6) provides Hash#compact and Hash#compact! natively, so requiring active_support/core_ext/hash/compact is no longer necessary. Requiring it will raise LoadError in Rails 6.1."
+ActiveSupport::Deprecation.warn "Ruby 2.5+ (required by Rails 6) provides Hash#compact and Hash#compact! natively, so requiring active_support/core_ext/hash/compact is no longer necessary. Requiring it will raise LoadError in Rails 6.1."
diff --git a/activesupport/lib/active_support/core_ext/hash/deep_transform_values.rb b/activesupport/lib/active_support/core_ext/hash/deep_transform_values.rb
new file mode 100644
index 0000000000..720a1f67c8
--- /dev/null
+++ b/activesupport/lib/active_support/core_ext/hash/deep_transform_values.rb
@@ -0,0 +1,46 @@
+# frozen_string_literal: true
+
+class Hash
+ # Returns a new hash with all keys converted by the block operation.
+ # This includes the keys from the root hash and from all
+ # nested hashes and arrays.
+ #
+ # hash = { person: { name: 'Rob', age: '28' } }
+ #
+ # hash.deep_transform_values{ |value| value.to_s.upcase }
+ # # => {person: {name: "ROB", age: "28"}}
+ def deep_transform_values(&block)
+ _deep_transform_values_in_object(self, &block)
+ end
+
+ # Destructively converts all values by using the block operation.
+ # This includes the values from the root hash and from all
+ # nested hashes and arrays.
+ def deep_transform_values!(&block)
+ _deep_transform_values_in_object!(self, &block)
+ end
+
+ private
+ # support methods for deep transforming nested hashes and arrays
+ def _deep_transform_values_in_object(object, &block)
+ case object
+ when Hash
+ object.transform_values { |value| _deep_transform_values_in_object(value, &block) }
+ when Array
+ object.map { |e| _deep_transform_values_in_object(e, &block) }
+ else
+ yield(object)
+ end
+ end
+
+ def _deep_transform_values_in_object!(object, &block)
+ case object
+ when Hash
+ object.transform_values! { |value| _deep_transform_values_in_object!(value, &block) }
+ when Array
+ object.map! { |e| _deep_transform_values_in_object!(e, &block) }
+ else
+ yield(object)
+ end
+ end
+end
diff --git a/activesupport/lib/active_support/core_ext/hash/except.rb b/activesupport/lib/active_support/core_ext/hash/except.rb
index 6258610c98..5013812460 100644
--- a/activesupport/lib/active_support/core_ext/hash/except.rb
+++ b/activesupport/lib/active_support/core_ext/hash/except.rb
@@ -10,7 +10,7 @@ class Hash
# This is useful for limiting a set of parameters to everything but a few known toggles:
# @person.update(params[:person].except(:admin))
def except(*keys)
- dup.except!(*keys)
+ slice(*self.keys - keys)
end
# Removes the given keys from hash and returns it.
diff --git a/activesupport/lib/active_support/core_ext/hash/keys.rb b/activesupport/lib/active_support/core_ext/hash/keys.rb
index bdf196ec3d..7d3495db2c 100644
--- a/activesupport/lib/active_support/core_ext/hash/keys.rb
+++ b/activesupport/lib/active_support/core_ext/hash/keys.rb
@@ -1,35 +1,6 @@
# frozen_string_literal: true
class Hash
- # Returns a new hash with all keys converted using the +block+ operation.
- #
- # hash = { name: 'Rob', age: '28' }
- #
- # hash.transform_keys { |key| key.to_s.upcase } # => {"NAME"=>"Rob", "AGE"=>"28"}
- #
- # If you do not provide a +block+, it will return an Enumerator
- # for chaining with other methods:
- #
- # hash.transform_keys.with_index { |k, i| [k, i].join } # => {"name0"=>"Rob", "age1"=>"28"}
- def transform_keys
- return enum_for(:transform_keys) { size } unless block_given?
- result = {}
- each_key do |key|
- result[yield(key)] = self[key]
- end
- result
- end unless method_defined? :transform_keys
-
- # Destructively converts all keys using the +block+ operations.
- # Same as +transform_keys+ but modifies +self+.
- def transform_keys!
- return enum_for(:transform_keys!) { size } unless block_given?
- keys.each do |key|
- self[yield(key)] = delete(key)
- end
- self
- end unless method_defined? :transform_keys!
-
# Returns a new hash with all keys converted to strings.
#
# hash = { name: 'Rob', age: '28' }
diff --git a/activesupport/lib/active_support/core_ext/hash/slice.rb b/activesupport/lib/active_support/core_ext/hash/slice.rb
index e07a5498ff..3d0f8a1e62 100644
--- a/activesupport/lib/active_support/core_ext/hash/slice.rb
+++ b/activesupport/lib/active_support/core_ext/hash/slice.rb
@@ -1,29 +1,6 @@
# frozen_string_literal: true
class Hash
- # Slices a hash to include only the given keys. Returns a hash containing
- # the given keys.
- #
- # { a: 1, b: 2, c: 3, d: 4 }.slice(:a, :b)
- # # => {:a=>1, :b=>2}
- #
- # This is useful for limiting an options hash to valid keys before
- # passing to a method:
- #
- # def search(criteria = {})
- # criteria.assert_valid_keys(:mass, :velocity, :time)
- # end
- #
- # search(options.slice(:mass, :velocity, :time))
- #
- # If you have an array of keys you want to limit to, you should splat them:
- #
- # valid_keys = [:mass, :velocity, :time]
- # search(options.slice(*valid_keys))
- def slice(*keys)
- keys.each_with_object(Hash.new) { |k, hash| hash[k] = self[k] if has_key?(k) }
- end unless method_defined?(:slice)
-
# Replaces the hash with only the given keys.
# Returns a hash containing the removed key/value pairs.
#
diff --git a/activesupport/lib/active_support/core_ext/hash/transform_values.rb b/activesupport/lib/active_support/core_ext/hash/transform_values.rb
index fc15130c9e..e4aeb0e891 100644
--- a/activesupport/lib/active_support/core_ext/hash/transform_values.rb
+++ b/activesupport/lib/active_support/core_ext/hash/transform_values.rb
@@ -2,4 +2,4 @@
require "active_support/deprecation"
-ActiveSupport::Deprecation.warn "Ruby 2.4+ (required by Rails 6) provides Hash#transform_values natively, so requiring active_support/core_ext/hash/transform_values is no longer necessary. Requiring it will raise LoadError in Rails 6.1."
+ActiveSupport::Deprecation.warn "Ruby 2.5+ (required by Rails 6) provides Hash#transform_values natively, so requiring active_support/core_ext/hash/transform_values is no longer necessary. Requiring it will raise LoadError in Rails 6.1."