Class: Chef::Node::ImmutableArray

Inherits:
Array
  • Object
show all
Includes:
Immutablize, Mixin::ImmutablizeArray, Mixin::StateTracking
Defined in:
lib/chef/node/immutable_collections.rb

Overview

ImmutableArray

ImmutableArray is used to implement Array collections when reading node attributes.

ImmutableArray acts like an ordinary Array, except:

  • Methods that mutate the array are overridden to raise an error, making the collection more or less immutable.

  • Since this class stores values computed from a parent Chef::Node::Attribute’s values, it overrides all reader methods to detect staleness and raise an error if accessed when stale.

Constant Summary

Constants included from Mixin::ImmutablizeArray

Mixin::ImmutablizeArray::DISALLOWED_MUTATOR_METHODS

Instance Attribute Summary collapse

Attributes included from Mixin::StateTracking

#__node__, #__path__, #__precedence__, #__root__

Instance Method Summary collapse

Methods included from Immutablize

#convert_value

Methods included from Mixin::StateTracking

#[]=

Constructor Details

#initialize(array_data = []) ⇒ ImmutableArray

Returns a new instance of ImmutableArray.



97
98
99
# File 'lib/chef/node/immutable_collections.rb', line 97

def initialize(array_data = [])
  # Immutable collections no longer have initialized state
end

Instance Attribute Details

#short_circuit_attr_levelsObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

This can be set to e.g. [ :@default ] by the parent container to cause this container to only use the default level and to bypass deep merging (the common case is either default-level or automatic-level and we aren’t doing any deep merging). Right now it “optimized” for the case where we’re no longer merging anything and only tracking a single level, and setting this to anything other than a size=1 array would behave in a broken fashion. That could be fixed, but the perf boost would likely not be that large in the typical case.



153
154
155
# File 'lib/chef/node/immutable_collections.rb', line 153

def short_circuit_attr_levels
  @short_circuit_attr_levels
end

Instance Method Details

#[](*args) ⇒ Object



127
128
129
130
# File 'lib/chef/node/immutable_collections.rb', line 127

def [](*args)
  ensure_generated_cache!
  args.length > 1 ? return_normal_array(super) : super # correctly handle array slices
end

#dupObject



108
109
110
# File 'lib/chef/node/immutable_collections.rb', line 108

def dup
  Array.new(map { |e| safe_dup(e) })
end

#eachObject



76
77
78
79
80
81
# File 'lib/chef/node/immutable_collections.rb', line 76

def each
  ensure_generated_cache!
  # aggressively pre generate the cache, works around ruby being too smart and fiddling with internals
  internal_each { |i| i.ensure_generated_cache! if i.respond_to?(:ensure_generated_cache!) }
  super
end

#ensure_generated_cache!Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



139
140
141
142
# File 'lib/chef/node/immutable_collections.rb', line 139

def ensure_generated_cache!
  generate_cache unless @generated_cache
  @generated_cache = true
end

#resetObject



132
133
134
135
136
# File 'lib/chef/node/immutable_collections.rb', line 132

def reset
  @generated_cache = false
  @short_circuit_attr_level = nil
  internal_clear # redundant?
end

#return_normal_array(array) ⇒ Object

because sometimes ruby gives us back Arrays or ImmutableArrays out of objects from things like #uniq or array slices



84
85
86
87
88
89
90
# File 'lib/chef/node/immutable_collections.rb', line 84

def return_normal_array(array)
  if array.respond_to?(:internal_to_a, true)
    array.internal_to_a
  else
    array.to_a
  end
end

#safe_dup(e) ⇒ Object

For elements like Fixnums, true, nil…



102
103
104
105
106
# File 'lib/chef/node/immutable_collections.rb', line 102

def safe_dup(e)
  e.dup
rescue TypeError
  e
end

#to_aObject Also known as: to_array



112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/chef/node/immutable_collections.rb', line 112

def to_a
  Array.new(map do |v|
    case v
    when ImmutableArray
      v.to_a
    when ImmutableMash
      v.to_h
    else
      safe_dup(v)
    end
  end)
end

#uniqObject



92
93
94
95
# File 'lib/chef/node/immutable_collections.rb', line 92

def uniq
  ensure_generated_cache!
  return_normal_array(super)
end