mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Merge pull request #36880 from freeletics/multiple-merge
Support multiple arguments in `HashWithIndifferentAccess` for `merge` and update methods
This commit is contained in:
commit
6ebdab3239
3 changed files with 47 additions and 13 deletions
|
@ -1,3 +1,8 @@
|
||||||
|
* Support multiple arguments in `HashWithIndifferentAccess` for `merge` and `update` methods, to
|
||||||
|
follow Ruby 2.6 addition.
|
||||||
|
|
||||||
|
*Wojciech Wnętrzak*
|
||||||
|
|
||||||
* Allow initializing `thread_mattr_*` attributes via `:default` option
|
* Allow initializing `thread_mattr_*` attributes via `:default` option
|
||||||
|
|
||||||
class Scraper
|
class Scraper
|
||||||
|
|
|
@ -96,7 +96,7 @@ module ActiveSupport
|
||||||
|
|
||||||
alias_method :store, :[]=
|
alias_method :store, :[]=
|
||||||
|
|
||||||
# Updates the receiver in-place, merging in the hash passed as argument:
|
# Updates the receiver in-place, merging in the hashes passed as arguments:
|
||||||
#
|
#
|
||||||
# hash_1 = ActiveSupport::HashWithIndifferentAccess.new
|
# hash_1 = ActiveSupport::HashWithIndifferentAccess.new
|
||||||
# hash_1[:key] = 'value'
|
# hash_1[:key] = 'value'
|
||||||
|
@ -106,7 +106,10 @@ module ActiveSupport
|
||||||
#
|
#
|
||||||
# hash_1.update(hash_2) # => {"key"=>"New Value!"}
|
# hash_1.update(hash_2) # => {"key"=>"New Value!"}
|
||||||
#
|
#
|
||||||
# The argument can be either an
|
# hash = ActiveSupport::HashWithIndifferentAccess.new
|
||||||
|
# hash.update({ "a" => 1 }, { "b" => 2 }) # => { "a" => 1, "b" => 2 }
|
||||||
|
#
|
||||||
|
# The arguments can be either an
|
||||||
# <tt>ActiveSupport::HashWithIndifferentAccess</tt> or a regular +Hash+.
|
# <tt>ActiveSupport::HashWithIndifferentAccess</tt> or a regular +Hash+.
|
||||||
# In either case the merge respects the semantics of indifferent access.
|
# In either case the merge respects the semantics of indifferent access.
|
||||||
#
|
#
|
||||||
|
@ -121,18 +124,15 @@ module ActiveSupport
|
||||||
# hash_1[:key] = 10
|
# hash_1[:key] = 10
|
||||||
# hash_2['key'] = 12
|
# hash_2['key'] = 12
|
||||||
# hash_1.update(hash_2) { |key, old, new| old + new } # => {"key"=>22}
|
# hash_1.update(hash_2) { |key, old, new| old + new } # => {"key"=>22}
|
||||||
def update(other_hash)
|
def update(*other_hashes, &block)
|
||||||
if other_hash.is_a? HashWithIndifferentAccess
|
if other_hashes.one?
|
||||||
super(other_hash)
|
update_with_single_argument(other_hashes.first, block)
|
||||||
else
|
else
|
||||||
other_hash.to_hash.each_pair do |key, value|
|
other_hashes.each do |other_hash|
|
||||||
if block_given? && key?(key)
|
update_with_single_argument(other_hash, block)
|
||||||
value = yield(convert_key(key), self[key], value)
|
|
||||||
end
|
|
||||||
regular_writer(convert_key(key), convert_value(value))
|
|
||||||
end
|
end
|
||||||
self
|
|
||||||
end
|
end
|
||||||
|
self
|
||||||
end
|
end
|
||||||
|
|
||||||
alias_method :merge!, :update
|
alias_method :merge!, :update
|
||||||
|
@ -259,8 +259,8 @@ module ActiveSupport
|
||||||
# This method has the same semantics of +update+, except it does not
|
# This method has the same semantics of +update+, except it does not
|
||||||
# modify the receiver but rather returns a new hash with indifferent
|
# modify the receiver but rather returns a new hash with indifferent
|
||||||
# access with the result of the merge.
|
# access with the result of the merge.
|
||||||
def merge(hash, &block)
|
def merge(*hashes, &block)
|
||||||
dup.update(hash, &block)
|
dup.update(*hashes, &block)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Like +merge+ but the other way around: Merges the receiver into the
|
# Like +merge+ but the other way around: Merges the receiver into the
|
||||||
|
@ -393,6 +393,19 @@ module ActiveSupport
|
||||||
target.default = default
|
target.default = default
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def update_with_single_argument(other_hash, block)
|
||||||
|
if other_hash.is_a? HashWithIndifferentAccess
|
||||||
|
regular_update(other_hash, &block)
|
||||||
|
else
|
||||||
|
other_hash.to_hash.each_pair do |key, value|
|
||||||
|
if block && key?(key)
|
||||||
|
value = block.call(convert_key(key), self[key], value)
|
||||||
|
end
|
||||||
|
regular_writer(convert_key(key), convert_value(value))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -249,6 +249,14 @@ class HashWithIndifferentAccessTest < ActiveSupport::TestCase
|
||||||
assert [updated_with_strings, updated_with_symbols, updated_with_mixed].all? { |h| h.keys.size == 2 }
|
assert [updated_with_strings, updated_with_symbols, updated_with_mixed].all? { |h| h.keys.size == 2 }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_update_with_multiple_arguments
|
||||||
|
hash = HashWithIndifferentAccess.new
|
||||||
|
hash.update({ "a" => 1 }, { "b" => 2 })
|
||||||
|
|
||||||
|
assert_equal 1, hash["a"]
|
||||||
|
assert_equal 2, hash["b"]
|
||||||
|
end
|
||||||
|
|
||||||
def test_update_with_to_hash_conversion
|
def test_update_with_to_hash_conversion
|
||||||
hash = HashWithIndifferentAccess.new
|
hash = HashWithIndifferentAccess.new
|
||||||
hash.update HashByConversion.new(a: 1)
|
hash.update HashByConversion.new(a: 1)
|
||||||
|
@ -274,6 +282,14 @@ class HashWithIndifferentAccessTest < ActiveSupport::TestCase
|
||||||
assert_equal 2, hash["b"]
|
assert_equal 2, hash["b"]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_merging_with_multiple_arguments
|
||||||
|
hash = HashWithIndifferentAccess.new
|
||||||
|
merged = hash.merge({ "a" => 1 }, { "b" => 2 })
|
||||||
|
|
||||||
|
assert_equal 1, merged["a"]
|
||||||
|
assert_equal 2, merged["b"]
|
||||||
|
end
|
||||||
|
|
||||||
def test_merge_with_to_hash_conversion
|
def test_merge_with_to_hash_conversion
|
||||||
hash = HashWithIndifferentAccess.new
|
hash = HashWithIndifferentAccess.new
|
||||||
merged = hash.merge HashByConversion.new(a: 1)
|
merged = hash.merge HashByConversion.new(a: 1)
|
||||||
|
|
Loading…
Reference in a new issue