Skip to content

Instantly share code, notes, and snippets.

@hypomodern
Created May 22, 2012 15:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hypomodern/2769917 to your computer and use it in GitHub Desktop.
Save hypomodern/2769917 to your computer and use it in GitHub Desktop.
Ruby Hash#fetch_path
class Hash
def fetch_path(path, default = nil)
pieces = path.split('.', 2)
value = self[pieces[0]]
return value if value && !pieces[1]
return default if !value.respond_to?(:fetch_path) || !value
value.fetch_path(pieces[1], default)
end
end
require 'spec_helper'
describe Hash do
describe "#fetch_path" do
let(:a_hash) {
{ 'foo' => { 'bar' => { 'baz' => 'quux' }, 'ip' => 17 }}
}
it "allows you to safely reach into a hash through many levels" do
a_hash.fetch_path('foo.bar.baz').should == 'quux'
end
it "works in a trivial case (but just use #fetch plz!)" do
a_hash.fetch_path('foo').should == { 'bar' => { 'baz' => 'quux' }, 'ip' => 17 }
end
it "returns nil if you don't supply a default and the keypath doesn't exist" do
a_hash.fetch_path('foo.b').should be_nil
end
it "returns the default if it cannot follow the path through and one is supplied" do
a_hash.fetch_path('foo.b', 'a_default').should == 'a_default'
end
it "returns the default if the path terminates in a non-hash early" do
a_hash.fetch_path('foo.ip.ping', 'pong').should == 'pong'
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment