summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorErol Fornoles <erol.fornoles@gmail.com>2014-12-29 09:56:11 +0800
committerErol Fornoles <erol.fornoles@gmail.com>2014-12-30 01:49:26 +0800
commit725c3ceacb2482f26e1832baaae99d8899ea3d1e (patch)
tree7c22de2f02d1ac133ddd210437ba43b9bed845a8
parenta18864fe1d079daf3eda5cf14a168ef6abd6403c (diff)
downloadhashie-725c3ceacb2482f26e1832baaae99d8899ea3d1e.tar.gz
Fix handling of default proc values in Mash
-rw-r--r--CHANGELOG.md1
-rw-r--r--lib/hashie/mash.rb15
-rw-r--r--spec/hashie/mash_spec.rb32
3 files changed, 41 insertions, 7 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ce62a40..ba60812 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,7 @@
* [#251](https://github.com/intridea/hashie/pull/251): Add block to indifferent access #fetch - [@jgraichen](https://github.com/jgraichen).
* [#252](https://github.com/intridia/hashie/pull/252): Add support for conditionally required Hashie::Dash attributes - [@ccashwell](https://github.com/ccashwell).
* [#256](https://github.com/intridia/hashie/pull/256): Inherit key coercions - [@Erol](https://github.com/Erol).
+* [#259](https://github.com/intridia/hashie/pull/259): Fix handling of default proc values in Mash - [@Erol](https://github.com/Erol).
* Your contribution here.
## 3.3.2 (11/26/2014)
diff --git a/lib/hashie/mash.rb b/lib/hashie/mash.rb
index 6d30a94..5d9e847 100644
--- a/lib/hashie/mash.rb
+++ b/lib/hashie/mash.rb
@@ -61,13 +61,13 @@ module Hashie
SUFFIXES_PARSER = /(.*?)([#{ALLOWED_SUFFIXES.join}]?)$/
def self.load(path, options = {})
- @_mashes ||= new do |h, file_path|
- fail ArgumentError, "The following file doesn't exist: #{file_path}" unless File.file?(file_path)
+ @_mashes ||= new
- parser = options.fetch(:parser) { Hashie::Extensions::Parsers::YamlErbParser }
- h[file_path] = new(parser.perform(file_path)).freeze
- end
- @_mashes[path]
+ return @_mashes[path] if @_mashes.key?(path)
+ fail ArgumentError, "The following file doesn't exist: #{path}" unless File.file?(path)
+
+ parser = options.fetch(:parser) { Hashie::Extensions::Parsers::YamlErbParser }
+ @_mashes[path] = new(parser.perform(path)).freeze
end
def to_module(mash_method_name = :settings)
@@ -106,6 +106,7 @@ module Hashie
# Retrieves an attribute set in the Mash. Will convert
# any key passed in to a string before retrieving.
def custom_reader(key)
+ default_proc.call(self, key) if default_proc && !key?(key)
value = regular_reader(convert_key(key))
yield value if block_given?
value
@@ -245,7 +246,7 @@ module Hashie
when '_'
underbang_reader(name)
else
- default(method_name)
+ self[method_name]
end
end
diff --git a/spec/hashie/mash_spec.rb b/spec/hashie/mash_spec.rb
index 77adc25..53a7982 100644
--- a/spec/hashie/mash_spec.rb
+++ b/spec/hashie/mash_spec.rb
@@ -402,6 +402,38 @@ describe Hashie::Mash do
expect(initial.test?).to be_truthy
end
+ it 'allows assignment of an empty array in a default block' do
+ initial = Hashie::Mash.new { |h, k| h[k] = [] }
+ initial.hello << 100
+ expect(initial.hello).to eq [100]
+ initial['hi'] << 100
+ expect(initial['hi']).to eq [100]
+ end
+
+ it 'allows assignment of a non-empty array in a default block' do
+ initial = Hashie::Mash.new { |h, k| h[k] = [100] }
+ initial.hello << 200
+ expect(initial.hello).to eq [100, 200]
+ initial['hi'] << 200
+ expect(initial['hi']).to eq [100, 200]
+ end
+
+ it 'allows assignment of an empty hash in a default block' do
+ initial = Hashie::Mash.new { |h, k| h[k] = {} }
+ initial.hello[:a] = 100
+ expect(initial.hello).to eq Hashie::Mash.new(a: 100)
+ initial[:hi][:a] = 100
+ expect(initial[:hi]).to eq Hashie::Mash.new(a: 100)
+ end
+
+ it 'allows assignment of a non-empty hash in a default block' do
+ initial = Hashie::Mash.new { |h, k| h[k] = { a: 100 } }
+ initial.hello[:b] = 200
+ expect(initial.hello).to eq Hashie::Mash.new(a: 100, b: 200)
+ initial[:hi][:b] = 200
+ expect(initial[:hi]).to eq Hashie::Mash.new(a: 100, b: 200)
+ end
+
it 'converts Hashie::Mashes within Arrays back to Hashes' do
initial_hash = { 'a' => [{ 'b' => 12, 'c' => ['d' => 50, 'e' => 51] }, 23] }
converted = Hashie::Mash.new(initial_hash)