summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md1
-rw-r--r--lib/hashie/rash.rb26
-rw-r--r--spec/hashie/rash_spec.rb27
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