Created
May 22, 2012 15:51
-
-
Save hypomodern/2769917 to your computer and use it in GitHub Desktop.
Ruby Hash#fetch_path
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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