aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSean Griffin <sean@seantheprogrammer.com>2015-10-29 09:54:55 -0600
committerSean Griffin <sean@seantheprogrammer.com>2015-10-29 09:54:55 -0600
commitddb886ef1338e0e4fa84d6d8ba55161da34d91aa (patch)
tree7978a76a0c0db50f220402e05e9f799354068366
parent90dbfdcba2110eb40f5c0c3a1d4c1d6ed46f5ab5 (diff)
parent6e574e8a11635ec4e579e5b247f6492b9bdc9279 (diff)
downloadrails-ddb886ef1338e0e4fa84d6d8ba55161da34d91aa.tar.gz
rails-ddb886ef1338e0e4fa84d6d8ba55161da34d91aa.tar.bz2
rails-ddb886ef1338e0e4fa84d6d8ba55161da34d91aa.zip
Merge pull request #16357 from gchan/hwia-respects-to-hash-default
`HashWithIndifferentAccess.new` respects the default value or proc on objects that respond to `#to_hash`
-rw-r--r--activesupport/CHANGELOG.md6
-rw-r--r--activesupport/lib/active_support/core_ext/hash/indifferent_access.rb2
-rw-r--r--activesupport/lib/active_support/hash_with_indifferent_access.rb14
-rw-r--r--activesupport/test/core_ext/hash_ext_test.rb18
4 files changed, 32 insertions, 8 deletions
diff --git a/activesupport/CHANGELOG.md b/activesupport/CHANGELOG.md
index 3705fc57fc..7c0f3eae80 100644
--- a/activesupport/CHANGELOG.md
+++ b/activesupport/CHANGELOG.md
@@ -1,3 +1,9 @@
+* `HashWithIndifferentAccess.new` respects the default value or proc on objects
+ that respond to `#to_hash`. `.new_from_hash_copying_default` simply invokes `.new`.
+ All calls to `.new_from_hash_copying_default` are replaced with `.new`.
+
+ *Gordon Chan*
+
* Change Integer#year to return a Fixnum instead of a Float to improve
consistency.
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 28cb3e2a3b..6df7b4121b 100644
--- a/activesupport/lib/active_support/core_ext/hash/indifferent_access.rb
+++ b/activesupport/lib/active_support/core_ext/hash/indifferent_access.rb
@@ -6,7 +6,7 @@ class Hash
#
# { a: 1 }.with_indifferent_access['a'] # => 1
def with_indifferent_access
- ActiveSupport::HashWithIndifferentAccess.new_from_hash_copying_default(self)
+ ActiveSupport::HashWithIndifferentAccess.new(self)
end
# Called when object is nested under an object that receives
diff --git a/activesupport/lib/active_support/hash_with_indifferent_access.rb b/activesupport/lib/active_support/hash_with_indifferent_access.rb
index 0371f760b0..3edeeb0029 100644
--- a/activesupport/lib/active_support/hash_with_indifferent_access.rb
+++ b/activesupport/lib/active_support/hash_with_indifferent_access.rb
@@ -59,6 +59,10 @@ module ActiveSupport
if constructor.respond_to?(:to_hash)
super()
update(constructor)
+
+ hash = constructor.to_hash
+ self.default = hash.default if hash.default
+ self.default_proc = hash.default_proc if hash.default_proc
else
super(constructor)
end
@@ -73,11 +77,7 @@ module ActiveSupport
end
def self.new_from_hash_copying_default(hash)
- hash = hash.to_hash
- new(hash).tap do |new_hash|
- new_hash.default = hash.default
- new_hash.default_proc = hash.default_proc if hash.default_proc
- end
+ new(hash)
end
def self.[](*args)
@@ -206,7 +206,7 @@ module ActiveSupport
# hash['a'] = nil
# hash.reverse_merge(a: 0, b: 1) # => {"a"=>nil, "b"=>1}
def reverse_merge(other_hash)
- super(self.class.new_from_hash_copying_default(other_hash))
+ super(self.class.new(other_hash))
end
# Same semantics as +reverse_merge+ but modifies the receiver in-place.
@@ -219,7 +219,7 @@ module ActiveSupport
# h = { "a" => 100, "b" => 200 }
# h.replace({ "c" => 300, "d" => 400 }) # => {"c"=>300, "d"=>400}
def replace(other_hash)
- super(self.class.new_from_hash_copying_default(other_hash))
+ super(self.class.new(other_hash))
end
# Removes the specified key from the hash.
diff --git a/activesupport/test/core_ext/hash_ext_test.rb b/activesupport/test/core_ext/hash_ext_test.rb
index 4624338df1..1d9b56b1b4 100644
--- a/activesupport/test/core_ext/hash_ext_test.rb
+++ b/activesupport/test/core_ext/hash_ext_test.rb
@@ -1044,6 +1044,24 @@ class HashExtTest < ActiveSupport::TestCase
assert_nothing_raised { HashWithIndifferentAccess.new_from_hash_copying_default(hash) }
end
+
+ def test_new_with_to_hash_conversion_copies_default
+ normal_hash = Hash.new(3)
+ normal_hash[:a] = 1
+
+ hash = HashWithIndifferentAccess.new(HashByConversion.new(normal_hash))
+ assert_equal 1, hash[:a]
+ assert_equal 3, hash[:b]
+ end
+
+ def test_new_with_to_hash_conversion_copies_default_proc
+ normal_hash = Hash.new { 1 + 2 }
+ normal_hash[:a] = 1
+
+ hash = HashWithIndifferentAccess.new(HashByConversion.new(normal_hash))
+ assert_equal 1, hash[:a]
+ assert_equal 3, hash[:b]
+ end
end
class IWriteMyOwnXML