Class: Chef::Node::ImmutableMash
- Includes:
- CommonAPI, Immutablize
- Defined in:
- lib/chef/node/immutable_collections.rb
Overview
ImmutableMash
ImmutableMash implements Hash/Dict behavior for reading values from node attributes.
ImmutableMash acts like a Mash (Hash that is indifferent to String or Symbol keys), with some important exceptions:
-
Methods that mutate state are overridden to raise an error instead.
-
Methods that read from the collection are overriden so that they check if the Chef::Node::Attribute has been modified since an instance of this class was generated. An error is raised if the object detects that it is stale.
-
Values can be accessed in attr_reader-like fashion via method_missing.
Constant Summary collapse
- DISALLOWED_MUTATOR_METHODS =
[ :[]=, :clear, :collect!, :default=, :default_proc=, :delete, :delete_if, :keep_if, :map!, :merge!, :update, :reject!, :replace, :select!, :shift, :write, :write!, :unlink, :unlink!, ]
Instance Method Summary collapse
-
#convert_value(value) ⇒ Object
Mash uses #convert_value to mashify values on input.
-
#dup ⇒ Object
NOTE: #default and #default= are likely to be pretty confusing.
-
#initialize(mash_data) ⇒ ImmutableMash
constructor
A new instance of ImmutableMash.
- #method_missing(symbol, *args) ⇒ Object
- #public_method_that_only_deep_merge_should_use(key, value) ⇒ Object
- #to_hash ⇒ Object
Methods included from CommonAPI
#exist?, #read, #read!, #unlink, #unlink!, #write, #write!
Methods included from Immutablize
Methods inherited from Mash
#[]=, #default, #delete, #except, #fetch, from_hash, #initialize_copy, #key?, #merge, #regular_update, #regular_writer, #stringify_keys!, #symbolize_keys, #update, #values_at
Constructor Details
#initialize(mash_data) ⇒ ImmutableMash
Returns a new instance of ImmutableMash.
172 173 174 175 176 |
# File 'lib/chef/node/immutable_collections.rb', line 172 def initialize(mash_data) mash_data.each do |key, value| internal_set(key, immutablize(value)) end end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(symbol, *args) ⇒ Object
192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 |
# File 'lib/chef/node/immutable_collections.rb', line 192 def method_missing(symbol, *args) if symbol == :to_ary super elsif args.empty? if key?(symbol) self[symbol] else raise NoMethodError, "Undefined method or attribute `#{symbol}' on `node'" end # This will raise a ImmutableAttributeModification error: elsif symbol.to_s =~ /=$/ key_to_set = symbol.to_s[/^(.+)=$/, 1] self[key_to_set] = (args.length == 1 ? args[0] : args) else raise NoMethodError, "Undefined node attribute or method `#{symbol}' on `node'" end end |
Instance Method Details
#convert_value(value) ⇒ Object
Mash uses #convert_value to mashify values on input. Since we’re handling this ourselves, override it to be a no-op
212 213 214 |
# File 'lib/chef/node/immutable_collections.rb', line 212 def convert_value(value) value end |
#dup ⇒ Object
NOTE: #default and #default= are likely to be pretty confusing. For a regular ruby Hash, they control what value is returned for, e.g.,
hash[:no_such_key] #=> hash.default
Of course, ‘default’ has a specific meaning in Chef-land
221 222 223 |
# File 'lib/chef/node/immutable_collections.rb', line 221 def dup Mash.new(self) end |
#public_method_that_only_deep_merge_should_use(key, value) ⇒ Object
178 179 180 |
# File 'lib/chef/node/immutable_collections.rb', line 178 def public_method_that_only_deep_merge_should_use(key, value) internal_set(key, immutablize(value)) end |
#to_hash ⇒ Object
225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 |
# File 'lib/chef/node/immutable_collections.rb', line 225 def to_hash h = Hash.new each_pair do |k, v| h[k] = case v when ImmutableMash v.to_hash when ImmutableArray v.to_a else v end end h end |