diff options
author | Michael Herold <michael.j.herold@gmail.com> | 2018-02-04 15:58:39 -0600 |
---|---|---|
committer | Michael Herold <michael.j.herold@gmail.com> | 2018-02-04 15:58:39 -0600 |
commit | 4c880a8a10611baae6e95376492428202242b6de (patch) | |
tree | b08db3e60a5fd65d3b2227ea0ac7f2189b0b528d | |
parent | d3279ba97b1ab2375775d672d7fca2f02cee7e71 (diff) | |
download | hashie-4c880a8a10611baae6e95376492428202242b6de.tar.gz |
Propagate Mash `default_proc` to sub-Hashes
In the case where you want to set deeply nested values through chained calls to
the `#[]` method or through method accessors (without using the bang methods),
you might set a `default_proc` on a Mash that recursively creates the key as you
access it. Previously, the `default_proc` was not being propagated down to
sub-Hashes because the way that `#dup` was written wasn't passing the
`default_proc` do the duplicated object.
Now, the `default_proc` is correctly being sent to the duplicated object, which
allows this pattern to work:
```ruby
h = Hashie::Mash.new { |mash, key| mash[key] = mash.class.new(&mash.default_proc) }
h.a.b.c = :xyz
h[:a][:b][:c] #=> :xyz
h[:x][:y][:z] = :abc
h.x.y.z #=> :abc
```
-rw-r--r-- | CHANGELOG.md | 1 | ||||
-rw-r--r-- | lib/hashie/mash.rb | 2 | ||||
-rw-r--r-- | spec/hashie/mash_spec.rb | 7 |
3 files changed, 9 insertions, 1 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 62d88a7..f0e9fc7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,6 +28,7 @@ scheme are considered to be bugs. ### Fixed +* [#435](https://github.com/intridea/hashie/pull/435): Mash `default_proc`s are now propagated down to nested sub-Hashes - [@michaelherold](https://github.com/michaelherold). * Your contribution here. ### Security diff --git a/lib/hashie/mash.rb b/lib/hashie/mash.rb index a6d1347..d995138 100644 --- a/lib/hashie/mash.rb +++ b/lib/hashie/mash.rb @@ -186,7 +186,7 @@ module Hashie alias_method :regular_dup, :dup # Duplicates the current mash as a new mash. def dup - self.class.new(self, default) + self.class.new(self, default, &default_proc) end alias_method :regular_key?, :key? diff --git a/spec/hashie/mash_spec.rb b/spec/hashie/mash_spec.rb index 162d982..1a0ad4f 100644 --- a/spec/hashie/mash_spec.rb +++ b/spec/hashie/mash_spec.rb @@ -457,6 +457,13 @@ describe Hashie::Mash do expect(initial.test?).to be_truthy end + it 'allows propagation of a default block' do + h = Hashie::Mash.new { |mash, key| mash[key] = mash.class.new(&mash.default_proc) } + expect { h[:x][:y][:z] = :xyz }.not_to raise_error + expect(h.x.y.z).to eq(:xyz) + expect(h[:x][:y][:z]).to eq(:xyz) + end + it 'allows assignment of an empty array in a default block' do initial = Hashie::Mash.new { |h, k| h[k] = [] } initial.hello << 100 |