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`
This commit is contained in:
Sean Griffin 2015-10-29 09:54:55 -06:00
commit ddb886ef13
4 changed files with 32 additions and 8 deletions

View File

@ -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.

View File

@ -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

View File

@ -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.

View File

@ -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