diff options
-rw-r--r-- | CHANGELOG.md | 1 | ||||
-rw-r--r-- | lib/hashie/rash.rb | 26 | ||||
-rw-r--r-- | spec/hashie/rash_spec.rb | 27 |
3 files changed, 54 insertions, 0 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 1643152..f1f33dd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ * [#183](https://github.com/intridea/hashie/pull/183): Added Mash#load with YAML file support - [@gregory](https://github.com/gregory). * [#197](https://github.com/intridea/hashie/pull/197): Dont convert keys to string on initalization of mash - [@gregory](https://github.com/gregory). * [#201](https://github.com/intridea/hashie/pull/201): Hashie::Trash transforms can be inherited - [@fobocaster](https://github.com/fobocaster). +* [#189](https://github.com/intridea/hashie/pull/189): Added Rash#fetch - [@medcat](https://github.com/medcat). * Your contribution here. ## 3.2.0 (7/10/2014) diff --git a/lib/hashie/rash.rb b/lib/hashie/rash.rb index abbff8e..1e059f3 100644 --- a/lib/hashie/rash.rb +++ b/lib/hashie/rash.rb @@ -61,6 +61,28 @@ module Hashie end # + # Raise (or yield) unless something matches the key. + # + def fetch(*args) + fail ArgumentError, "Expected 1-2 arguments, got #{args.length}" \ + unless (1..2).cover?(args.length) + + key, default = args + + all(key) do |value| + return value + end + + if block_given? + yield key + elsif default + default + else + fail KeyError, "key not found: #{key.inspect}" + end + end + + # # Return everything that matches the query. # def all(query) @@ -106,6 +128,10 @@ module Hashie @hash.send(*args, &block) end + def respond_to_missing?(*args) + @hash.respond_to?(*args) + end + private def optimize_if_necessary! diff --git a/spec/hashie/rash_spec.rb b/spec/hashie/rash_spec.rb index 20b2652..914e7b4 100644 --- a/spec/hashie/rash_spec.rb +++ b/spec/hashie/rash_spec.rb @@ -47,4 +47,31 @@ describe Hashie::Rash do expect(subject['abcdef']).to eq 'bcd' expect(subject['ffffff']).to be_nil end + + it 'finds using the find method' do + expect(subject.fetch(10.1)).to eq 'rangey' + expect(subject.fetch(true)).to be false + end + + it 'raises in find unless a key matches' do + expect { subject.fetch(1_000_000) }.to raise_error(KeyError) + end + + it 'yields in find unless a key matches' do + expect { |y| subject.fetch(1_000_000, &y) }.to yield_control + expect { |y| subject.fetch(10.1, &y) }.to_not yield_control + end + + it 'gives a default value' do + expect(subject.fetch(10.1, 'noop')).to eq 'rangey' + expect(subject.fetch(1_000_000, 'noop')).to eq 'noop' + expect(subject.fetch(1_000_000) { 'noop' }).to eq 'noop' + expect(subject.fetch(1_000_000) { |k| k }).to eq 1_000_000 + expect(subject.fetch(1_000_000, 'noop') { 'op' }).to eq 'op' + end + + it 'responds to hash methods' do + expect(subject.respond_to?(:to_a)).to be true + expect(subject.methods).to_not include(:to_a) + end end |