module Chef::Node::CommonAPI
shared API between VividMash
and ImmutableMash
, writer code can be ‘shared’ to keep it logically in this file by adding them to the block list in ImmutableMash
.
Public Instance Methods
return true or false based on if the attribute exists
# File lib/chef/node/common_api.rb, line 73 def exist?(*path) path.inject(self) do |memo, key| return false unless valid_container?(memo, key) if memo.is_a?(Hash) if memo.key?(key) memo[key] else return false end elsif memo.is_a?(Array) if memo.length > key memo[key] else return false end end end true end
this is a safe non-autovivifying reader that returns nil if the attribute does not exist
# File lib/chef/node/common_api.rb, line 95 def read(*path) read!(*path) rescue Chef::Exceptions::NoSuchAttribute nil end
non-autovivifying reader that throws an exception if the attribute does not exist
# File lib/chef/node/common_api.rb, line 104 def read!(*path) raise Chef::Exceptions::NoSuchAttribute.new(path.join ".") unless exist?(*path) path.inject(self) do |memo, key| memo[key] end end
FIXME:(?) does anyone really like the autovivifying reader that we have and wants the same behavior? readers that write? ugh…
# File lib/chef/node/common_api.rb, line 114 def unlink(*path, last) hash = path.empty? ? self : read(*path) return nil unless hash.is_a?(Hash) || hash.is_a?(Array) hash.delete(last) end
# File lib/chef/node/common_api.rb, line 121 def unlink!(*path) raise Chef::Exceptions::NoSuchAttribute unless exist?(*path) unlink(*path) end
-
autovivifying / autoreplacing writer
-
non-container-ey intermediate objects are replaced with hashes
# File lib/chef/node/common_api.rb, line 34 def write(*args, &block) value = block_given? ? yield : args.pop last = args.pop prev_memo = prev_key = nil chain = args.inject(self) do |memo, key| unless valid_container?(memo, key) prev_memo[prev_key] = {} memo = prev_memo[prev_key] end prev_memo = memo prev_key = key memo[key] end unless valid_container?(chain, last) prev_memo[prev_key] = {} chain = prev_memo[prev_key] end chain[last] = value end
this autovivifies, but can throw NoSuchAttribute when trying to access [] on something that is not a container (“schema violation” issues).
# File lib/chef/node/common_api.rb, line 57 def write!(*args, &block) value = block_given? ? yield : args.pop last = args.pop obj = args.inject(self) do |memo, key| raise Chef::Exceptions::AttributeTypeMismatch unless valid_container?(memo, key) memo[key] end raise Chef::Exceptions::AttributeTypeMismatch unless valid_container?(obj, last) obj[last] = value end
Private Instance Methods
method-style access to attributes
# File lib/chef/node/common_api.rb, line 26 def valid_container?(obj, key) obj.is_a?(Hash) || (obj.is_a?(Array) && key.is_a?(Integer)) end