-
-
Save pier-oliviert/1495250 to your computer and use it in GitHub Desktop.
Hash#value_at_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 | |
# Returns the value at the specified path. | |
# For example, [:foo, :bar, :baz] as a path would return the | |
# value at self[:foo][:bar][:baz]. If self doesn't contain one of | |
# the keys specified in path, nil is returned. | |
# | |
# This method is useful as it simplifies statements such as: | |
# value = h[:a][:b][:c][:d] if h[:a] && h[:a][:b] && h[:a][:b][:c] | |
# to | |
# value = h.value_at_path([:a, :b, :c, :d]) | |
# | |
# @param Array path An array of keys specifying a deep-nested path | |
# @return Object the value object | |
def value_at_path(path) | |
raise ArgumentError unless path.is_a?(Array) | |
raise ArgumentError if path.include?(nil) | |
raise ArgumentError if path.empty? | |
if path.size == 1 | |
return self[path[0]] | |
else | |
if self[path[0]].respond_to?(:value_at_path) | |
return self[path[0]].value_at_path(path[1..-1]) | |
else | |
return nil | |
end | |
end | |
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 'test_helper' | |
class HashTest < ActiveSupport::TestCase | |
def setup | |
@h = { :a => { :b => {:c => 'foo'}}, :b => 'bar'} | |
end | |
test "value_at_path returns value if path exists" do | |
assert_equal 'foo', @h.value_at_path([:a, :b, :c]) | |
assert_equal 'bar', @h.value_at_path([:b]) | |
assert_equal @h[:a], @h.value_at_path([:a]) | |
assert_equal @h[:a][:b], @h.value_at_path([:a, :b]) | |
end | |
test "value_at_path returns value if path does not exist" do | |
assert_nil @h.value_at_path([:a, :b, :c, :d]) | |
assert_nil @h.value_at_path([:c]) | |
end | |
test "value_at_path raises an exception if specified path is invalid" do | |
assert_raise(ArgumentError) { @h.value_at_path([]) } | |
assert_raise(ArgumentError) { @h.value_at_path([nil]) } | |
assert_raise(ArgumentError) { @h.value_at_path('foo') } | |
assert_raise(ArgumentError) { @h.value_at_path(123) } | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment