add DeepMerge extension
This commit is contained in:
parent
f7cb5e2b3c
commit
e94b70f206
|
@ -34,7 +34,7 @@ applications such as an API client:
|
|||
include Hashie::Extensions::Coercion
|
||||
coerce_key :user, User
|
||||
end
|
||||
|
||||
|
||||
user_hash = {:name => "Bob"}
|
||||
Tweet.new(:user => user_hash)
|
||||
# => automatically calls User.coerce(user_hash) or
|
||||
|
@ -47,7 +47,7 @@ Hash-like class that is self-propagating.
|
|||
class SpecialHash < Hash
|
||||
include Hashie::Extensions::Coercion
|
||||
coerce_value Hash, SpecialHash
|
||||
|
||||
|
||||
def initialize(hash = {})
|
||||
super
|
||||
hash.each_pair do |k,v|
|
||||
|
@ -78,7 +78,7 @@ included as individual modules, i.e. `Hashie::Extensions::MethodReader`,
|
|||
class MyHash < Hash
|
||||
include Hashie::Extensions::MethodAccess
|
||||
end
|
||||
|
||||
|
||||
h = MyHash.new
|
||||
h.abc = 'def'
|
||||
h.abc # => 'def'
|
||||
|
@ -97,10 +97,23 @@ hash in question. This means you can safely merge together indifferent
|
|||
and non-indifferent hashes arbitrarily deeply without worrying about
|
||||
whether you'll be able to `hash[:other][:another]` properly.
|
||||
|
||||
### DeepMerge (Unimplemented)
|
||||
### DeepMerge
|
||||
|
||||
This extension *will* allow you to easily include a recursive merging
|
||||
system to any Hash descendant.
|
||||
This extension allow you to easily include a recursive merging
|
||||
system to any Hash descendant:
|
||||
|
||||
class MyHash < Hash
|
||||
include Hashie::Extensions::DeepMerge
|
||||
end
|
||||
|
||||
h1 = MyHash.new
|
||||
h2 = MyHash.new
|
||||
|
||||
h1 = {:x => {:y => [4,5,6]}, :z => [7,8,9]}
|
||||
h2 = {:x => {:y => [7,8,9]}, :z => "xyz"}
|
||||
|
||||
h1.deep_merge(h2) #=> { :x => {:y => [7, 8, 9]}, :z => "xyz" }
|
||||
h2.deep_merge(h1) #=> { :x => {:y => [4, 5, 6]}, :z => [7, 8, 9] }
|
||||
|
||||
## Mash
|
||||
|
||||
|
|
|
@ -1,7 +1,21 @@
|
|||
module Hashie
|
||||
module Extensions
|
||||
module DeepMerge
|
||||
# TODO: Implement deep merging.
|
||||
# Returns a new hash with +self+ and +other_hash+ merged recursively.
|
||||
def deep_merge(other_hash)
|
||||
(class << (h = dup); self; end).send :include, Hashie::Extensions::DeepMerge
|
||||
h.deep_merge!(other_hash)
|
||||
end
|
||||
|
||||
# Returns a new hash with +self+ and +other_hash+ merged recursively.
|
||||
# Modifies the receiver in place.
|
||||
def deep_merge!(other_hash)
|
||||
other_hash.each do |k,v|
|
||||
(class << (tv = self[k]); self; end).send :include, Hashie::Extensions::DeepMerge
|
||||
self[k] = tv.is_a?(::Hash) && v.is_a?(::Hash) ? tv.deep_merge(v) : v
|
||||
end
|
||||
self
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe Hashie::Extensions::DeepMerge do
|
||||
class DeepMergeHash < Hash; include Hashie::Extensions::DeepMerge end
|
||||
|
||||
subject{ DeepMergeHash }
|
||||
|
||||
let(:h1) { subject.new.merge(:a => "a", :b => "b", :c => { :c1 => "c1", :c2 => "c2", :c3 => { :d1 => "d1" } }) }
|
||||
let(:h2) { { :a => 1, :c => { :c1 => 2, :c3 => { :d2 => "d2" } } } }
|
||||
let(:expected_hash) { { :a => 1, :b => "b", :c => { :c1 => 2, :c2 => "c2", :c3 => { :d1 => "d1", :d2 => "d2" } } } }
|
||||
|
||||
it 'should deep merge two hashes' do
|
||||
h1.deep_merge(h2).should == expected_hash
|
||||
end
|
||||
|
||||
it 'should deep merge two hashes with bang method' do
|
||||
h1.deep_merge!(h2)
|
||||
h1.should == expected_hash
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue