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 71 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 92 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 99 def read!(*path) raise Chef::Exceptions::NoSuchAttribute 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 108 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 114 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| if !valid_container?(memo, key) prev_memo[prev_key] = {} memo = prev_memo[prev_key] end prev_memo = memo prev_key = key memo[key] end if !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