lib/redfish_client/resource.rb in redfish_client-0.2.2 vs lib/redfish_client/resource.rb in redfish_client-0.2.3
- old
+ new
@@ -62,40 +62,49 @@
# In addition to accessing values associated with keys, this function can
# also be used to access members of collection by directly indexing into
# Members array. This means that `res["Members"][3]` can be shortened into
# `res[3]`.
#
- # Accessing non-existent or indexing non-collection resource key will
- # raise `KeyError`. Accessing invalid index will raise `IndexError`.
+ # Indexing non-collection resource key will # raise `KeyError`.
#
# @param attr [String, Integer] key or index for accessing data
- # @return associated value
+ # @return associated value or `nil` if attr is missing
def [](attr)
if attr.is_a?(Integer)
raise(KeyError, "Not a collection.") unless key?("Members")
- cache("Members").fetch(attr)
+ cache("Members")[attr]
else
cache(attr)
end
end
+ # Safely access nested resource content.
+ #
+ # This function is an equivalent of safe navigation operator that can be
+ # used with arbitrary keys.
+ #
+ # Calling `res.dig("a", "b", "c")` is equivalent to `res.a&.b&.c` and
+ # `res["a"] && res["a"]["b"] && res["a"]["b"]["c"]`.
+ # @params keys [Array<Symbol, String>] sequence of keys to access
+ # @return associated value or `nil` if any key is missing
+ def dig(*keys)
+ keys.reduce(self) { |a, k| a.nil? ? nil : a[k] }
+ end
+
# Test if resource contains required key.
#
# @param name [String, Symbol] key name to test
# @return [Boolean] inclusion test result
def key?(name)
@content.key?(name.to_s)
end
# Convenience access for resource data.
#
- # Calling `resource.Value` is exactly the same as `resource["Value"]`. The
- # only difference is that accessing non-existent field will raise
- # NoMethodError instead of KeyError as `[]` method does.
- def method_missing(symbol, *args, &block)
- name = symbol.to_s
- key?(name) ? self[name] : super
+ # Calling `resource.Value` is exactly the same as `resource["Value"]`.
+ def method_missing(symbol, *_args, &_block)
+ self[symbol.to_s]
end
def respond_to_missing?(symbol, include_private = false)
key?(symbol.to_s) || super
end
@@ -185,14 +194,16 @@
raise NoODataId if path.nil? && !key?(field)
path || @content[field]
end
def cache(name)
- @cache[name] ||= build_resource(@content.fetch(name))
+ @cache[name] ||= build_resource(@content[name])
end
def build_resource(data)
+ return nil if data.nil?
+
case data
when Hash then build_hash_resource(data)
when Array then data.collect { |d| build_resource(d) }
else data
end
@@ -202,8 +213,10 @@
if data.key?("@odata.id")
Resource.new(@connector, oid: data["@odata.id"])
else
Resource.new(@connector, content: data)
end
+ rescue NoResource
+ nil
end
end
end