2016-03-18 22:14:41 +00:00
|
|
|
# author: Dominik Richter
|
|
|
|
# author: Christoph Hartmann
|
|
|
|
module ObjectTraverser
|
|
|
|
def extract_value(keys, value)
|
2017-10-06 17:24:31 +00:00
|
|
|
return nil if value.nil?
|
|
|
|
|
2016-03-18 22:14:41 +00:00
|
|
|
key = keys.shift
|
2017-10-06 17:24:31 +00:00
|
|
|
return nil if key.nil?
|
2016-03-18 22:14:41 +00:00
|
|
|
|
2017-10-06 17:24:31 +00:00
|
|
|
# if the current value is not a Hash or Array, it is undefined
|
|
|
|
# behavior so value will be assigned nil by default.
|
|
|
|
value = if value.is_a?(Array)
|
|
|
|
extract_from_array(key, value)
|
|
|
|
elsif value.is_a?(Hash)
|
|
|
|
extract_from_hash(key, value)
|
|
|
|
end
|
2016-03-18 22:14:41 +00:00
|
|
|
|
|
|
|
# if there are no more keys, just return the value
|
|
|
|
return value if keys.first.nil?
|
|
|
|
# if there are more keys, extract more
|
|
|
|
extract_value(keys.clone, value)
|
|
|
|
end
|
2017-10-06 17:24:31 +00:00
|
|
|
|
|
|
|
private
|
|
|
|
|
|
|
|
# If the values to return from is an Array, allow returning by index.
|
|
|
|
# Otherwise, support methods on the Array itself.
|
|
|
|
def extract_from_array(key, value)
|
2017-11-21 07:49:41 +00:00
|
|
|
if key.is_a?(Integer)
|
2017-10-06 17:24:31 +00:00
|
|
|
value[key]
|
|
|
|
elsif value.respond_to?(key.to_sym)
|
|
|
|
value.send(key.to_sym)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
# for Hashes, try to return the value by the key.
|
|
|
|
# We first try to find by the raw key before we stringify
|
|
|
|
# if the keys themselves are symbols, for example.
|
|
|
|
#
|
|
|
|
# This will return nil default if we can't find the key.
|
|
|
|
def extract_from_hash(key, value)
|
|
|
|
if value.key?(key)
|
|
|
|
value[key]
|
|
|
|
elsif value.key?(key.to_s)
|
|
|
|
value[key.to_s]
|
|
|
|
end
|
|
|
|
end
|
2016-03-18 22:14:41 +00:00
|
|
|
end
|