# class Chef::Node::ImmutableMash

## 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.

### Constants

DISALLOWED_MUTATOR_METHODS

### Public Class Methods

new(mash_data) click to toggle source

    # File lib/chef/node/immutable_collections.rb, line 154
    def initialize(mash_data)
      mash_data.each do |key, value|
        internal_set(key, immutablize(value))
      end
    end

### Public Instance Methods

convert_value(value) click to toggle source

Mash uses convert_value to mashify values on input. Since we're handling this ourselves, override it to be a no-op

    # File lib/chef/node/immutable_collections.rb, line 193
    def convert_value(value)
      value
    end

dup() click to toggle source

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

    # File lib/chef/node/immutable_collections.rb, line 202
    def dup
      Mash.new(self)
    end

method_missing(symbol, *args) click to toggle source

    # File lib/chef/node/immutable_collections.rb, line 175
    def method_missing(symbol, *args)
      if 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

to_hash() click to toggle source

    # File lib/chef/node/immutable_collections.rb, line 206
    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