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
|
||||
|
||||
class Scraper
|
||||
|
|
|
@ -96,7 +96,7 @@ module ActiveSupport
|
|||
|
||||
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[:key] = 'value'
|
||||
|
@ -106,7 +106,10 @@ module ActiveSupport
|
|||
#
|
||||
# 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+.
|
||||
# In either case the merge respects the semantics of indifferent access.
|
||||
#
|
||||
|
@ -121,18 +124,15 @@ module ActiveSupport
|
|||
# hash_1[:key] = 10
|
||||
# hash_2['key'] = 12
|
||||
# hash_1.update(hash_2) { |key, old, new| old + new } # => {"key"=>22}
|
||||
def update(other_hash)
|
||||
if other_hash.is_a? HashWithIndifferentAccess
|
||||
super(other_hash)
|
||||
def update(*other_hashes, &block)
|
||||
if other_hashes.one?
|
||||
update_with_single_argument(other_hashes.first, block)
|
||||
else
|
||||
other_hash.to_hash.each_pair do |key, value|
|
||||
if block_given? && key?(key)
|
||||
value = yield(convert_key(key), self[key], value)
|
||||
end
|
||||
regular_writer(convert_key(key), convert_value(value))
|
||||
other_hashes.each do |other_hash|
|
||||
update_with_single_argument(other_hash, block)
|
||||
end
|
||||
self
|
||||
end
|
||||
self
|
||||
end
|
||||
|
||||
alias_method :merge!, :update
|
||||
|
@ -259,8 +259,8 @@ module ActiveSupport
|
|||
# This method has the same semantics of +update+, except it does not
|
||||
# modify the receiver but rather returns a new hash with indifferent
|
||||
# access with the result of the merge.
|
||||
def merge(hash, &block)
|
||||
dup.update(hash, &block)
|
||||
def merge(*hashes, &block)
|
||||
dup.update(*hashes, &block)
|
||||
end
|
||||
|
||||
# Like +merge+ but the other way around: Merges the receiver into the
|
||||
|
@ -393,6 +393,19 @@ module ActiveSupport
|
|||
target.default = default
|
||||
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
|
||||
|
||||
|
|
|
@ -249,6 +249,14 @@ class HashWithIndifferentAccessTest < ActiveSupport::TestCase
|
|||
assert [updated_with_strings, updated_with_symbols, updated_with_mixed].all? { |h| h.keys.size == 2 }
|
||||
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
|
||||
hash = HashWithIndifferentAccess.new
|
||||
hash.update HashByConversion.new(a: 1)
|
||||
|
@ -274,6 +282,14 @@ class HashWithIndifferentAccessTest < ActiveSupport::TestCase
|
|||
assert_equal 2, hash["b"]
|
||||
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
|
||||
hash = HashWithIndifferentAccess.new
|
||||
merged = hash.merge HashByConversion.new(a: 1)
|
||||
|
|
Loading…
Reference in a new issue