Class: AttributeStruct

Inherits:
BasicObject
Defined in:
lib/attribute_struct/version.rb,
lib/attribute_struct/attribute_hash.rb,
lib/attribute_struct/attribute_struct.rb

Defined Under Namespace

Classes: AttributeHash, Version

Constant Summary collapse

VERSION =
Version.new('0.1.6')

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(*args, &block) ⇒ AttributeStruct

Returns a new instance of AttributeStruct.



43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/attribute_struct/attribute_struct.rb', line 43

def initialize(*args, &block)
  _klass.load_the_hash
  @_camel_keys = _klass.camel_keys
  @table = __hashish.new
  unless(args.empty?)
    if(args.size == 1 && args.first.is_a?(::Hash))
      _load(args.first)
    end
  end
  if(block)
    self.instance_exec(&block)
  end
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(sym, *args, &block) ⇒ Object

Dragons and unicorns all over in here



83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/attribute_struct/attribute_struct.rb', line 83

def method_missing(sym, *args, &block)
  if((s = sym.to_s).end_with?('='))
    s.slice!(-1, s.length)
    sym = s
  end
  sym = _process_key(sym)
  @table[sym] ||= _klass_new
  if(!args.empty? || block)
    if(args.empty? && block)
      base = @table[sym]
      if(block.arity == 0)
        base.instance_exec(&block)
      else
        base.instance_exec(base, &block)
      end
      @table[sym] = base
    elsif(!args.empty? && block)
      base = @table[sym]
      base = _klass_new unless base.is_a?(_klass)
      @table[sym] = base
      leaf = base
      args.each do |arg|
        leaf = base[arg]
        unless(leaf.is_a?(_klass))
          leaf = _klass_new
          base._set(arg, leaf)
          base = leaf
        end
      end
      if(block.arity == 0)
        leaf.instance_exec(&block)
      else
        leaf.instance_exec(leaf, &block)
      end
    else
      if(args.size > 1)
        @table[sym] = _klass_new unless @table[sym].is_a?(_klass)
        endpoint = args.inject(@table[sym]) do |memo, k|
          unless(memo[k].is_a?(_klass))
            memo._set(k, _klass_new)
          end
          memo[k]
        end
        return endpoint # custom break out
      else
        @table[sym] = args.first
      end
    end
  end
  @table[sym]
end

Class Attribute Details

.camel_keysObject

Global flag for camel cased keys



6
7
8
# File 'lib/attribute_struct/attribute_struct.rb', line 6

def camel_keys
  @camel_keys
end

.force_chefObject

Force tooling from Chef



8
9
10
# File 'lib/attribute_struct/attribute_struct.rb', line 8

def force_chef
  @force_chef
end

Instance Attribute Details

#_camel_keysObject

Flag for camel cased keys



41
42
43
# File 'lib/attribute_struct/attribute_struct.rb', line 41

def _camel_keys
  @_camel_keys
end

Class Method Details

.load_the_camelsObject

Loads helpers for camel casing



18
19
20
21
22
23
# File 'lib/attribute_struct/attribute_struct.rb', line 18

def load_the_camels
  unless(@camels_loaded)
    require 'attribute_struct/monkey_camels'
    @camels_loaded = true
  end
end

.load_the_hashObject

Determines what hash library to load based on availability



26
27
28
29
30
31
32
33
34
35
36
# File 'lib/attribute_struct/attribute_struct.rb', line 26

def load_the_hash
  unless(@hash_loaded)
    if(defined?(Chef) || force_chef)
      require 'chef/mash'
      require 'chef/mixin/deep_merge'
    else
      require 'attribute_struct/attribute_hash'
    end
    @hash_loaded = true
  end
end

Instance Method Details

#[](key) ⇒ Object

key

Object

Access data directly



66
67
68
# File 'lib/attribute_struct/attribute_struct.rb', line 66

def [](key)
  _data[_process_key(key)]
end

#__hashishObject

Returns a new Hash type instance based on what is available



224
225
226
# File 'lib/attribute_struct/attribute_struct.rb', line 224

def __hashish
  defined?(::Mash) ? ::Mash : ::AttributeStruct::AttributeHash
end

#_array(*args) ⇒ Object

args

Objects

Helper to create Arrays with nested AttributeStructs. Proc instances are automatically executed into new AttributeStruct instances



319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
# File 'lib/attribute_struct/attribute_struct.rb', line 319

def _array(*args)
  args.map do |maybe_block|
    if(maybe_block.is_a?(::Proc))
      klass = _klass_new
      if(maybe_block.arity > 0)
        klass.instance_exec(klass, &maybe_block)
      else
        klass.instance_exec(&maybe_block)
      end
      klass
    else
      maybe_block
    end
  end
end

#_camel_keys_actionObject

Returns value set via #_camel_keys_set



298
299
300
# File 'lib/attribute_struct/attribute_struct.rb', line 298

def _camel_keys_action
  @_camel_keys_set
end

#_camel_keys_set(v) ⇒ Object

v

Symbol (:auto_disable, :auto_enable)

Sets custom rule for processed keys



293
294
295
# File 'lib/attribute_struct/attribute_struct.rb', line 293

def _camel_keys_set(v)
  @_camel_keys_set = v
end

#_dataObject

Returns underlying data hash



153
154
155
# File 'lib/attribute_struct/attribute_struct.rb', line 153

def _data
  @table
end

#_deep_copy(thing = nil) ⇒ Object

thing

Object

Returns a proper deep copy



239
240
241
242
243
244
245
246
247
248
249
250
# File 'lib/attribute_struct/attribute_struct.rb', line 239

def _deep_copy(thing=nil)
  thing ||= _dump
  if(thing.is_a?(::Enumerable))
    val = thing.map{|v| v.is_a?(::Enumerable) ? _deep_copy(v) : _do_dup(v) }
  else
    val = _do_dup(thing)
  end
  if(thing.is_a?(::Hash))
    val = __hashish[*val.flatten(1)]
  end
  val
end

#_delete(key) ⇒ Object

key

Object

Delete entry in struct with key



159
160
161
# File 'lib/attribute_struct/attribute_struct.rb', line 159

def _delete(key)
  _data.delete(_process_key(key))
end

#_do_dup(v) ⇒ Object

Returns dup of value. Converts Symbol objects to strings



229
230
231
232
233
234
235
# File 'lib/attribute_struct/attribute_struct.rb', line 229

def _do_dup(v)
  begin
    v.dup
  rescue
    v.is_a?(::Symbol) ? v.to_s : v
  end
end

#_dumpObject

Dumps the current instance to a Hash



164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
# File 'lib/attribute_struct/attribute_struct.rb', line 164

def _dump
  processed = @table.map do |key, value|
    if(value.is_a?(::Enumerable))
      flat = value.map do |v|
        v.is_a?(_klass) ? v._dump : v
      end
      val = value.is_a?(::Hash) ? __hashish[*flat.flatten(1)] : flat
    elsif(value.is_a?(_klass))
      val = value._dump
    else
      val = value
    end
    [key, val]
  end
  __hashish[*processed.flatten(1)]
end

#_keysObject

Returns current keys within struct



148
149
150
# File 'lib/attribute_struct/attribute_struct.rb', line 148

def _keys
  _data.keys
end

#_klassObject Also known as: class

Helper to return class of current instance



278
279
280
# File 'lib/attribute_struct/attribute_struct.rb', line 278

def _klass
  ::AttributeStruct
end

#_klass_newObject

Helper to return new instance of current instance type



284
285
286
287
288
289
# File 'lib/attribute_struct/attribute_struct.rb', line 284

def _klass_new
  n = _klass.new
  n._camel_keys_set(_camel_keys_action)
  n._parent(self)
  n
end

#_load(hashish) ⇒ Object

hashish

Hash type object

Clears current instance data and replaces with provided hash



183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
# File 'lib/attribute_struct/attribute_struct.rb', line 183

def _load(hashish)
  @table.clear
  hashish.each do |key, value|
    if(value.is_a?(::Enumerable))
      flat = value.map do |v|
        v.is_a?(::Hash) ? _klass.new(v) : v
      end
      value = value.is_a?(::Hash) ? __hashish[*flat.flatten(1)] : flat
    end
    if(value.is_a?(::Hash))
      self._set(key)._load(value)
    else
      self._set(key, value)
    end
  end
  self
end

#_merge(target) ⇒ Object

target

AttributeStruct

Performs a deep merge and returns the resulting AttributeStruct



203
204
205
206
207
208
209
210
211
212
# File 'lib/attribute_struct/attribute_struct.rb', line 203

def _merge(target)
  source = _deep_copy
  dest = target._deep_copy
  if(defined?(::Mash))
    result = ::Chef::Mixin::DeepMerge.merge(source, dest)
  else
    result = source.deep_merge(dest)
  end
  _klass.new(result)
end

#_merge!(target) ⇒ Object

target

AttributeStruct

Performs a deep merge and updates the current instance with the resulting value



217
218
219
220
221
# File 'lib/attribute_struct/attribute_struct.rb', line 217

def _merge!(target)
  result = _merge(target)._dump
  _load(result)
  self
end

#_parent(obj = nil) ⇒ Object



302
303
304
305
# File 'lib/attribute_struct/attribute_struct.rb', line 302

def _parent(obj=nil)
  @_parent = obj if obj
  @_parent
end

#_process_key(key, *args) ⇒ Object

key

String or Symbol

Processes the key and returns value based on current settings



254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
# File 'lib/attribute_struct/attribute_struct.rb', line 254

def _process_key(key, *args)
  key = key.to_s
  if(_camel_keys && _camel_keys_action)
    case _camel_keys_action
    when :auto_disable
      key._no_hump
    when :auto_enable
      key._hump
    end
  end
  if((_camel_keys && key._camel?) || args.include?(:force))
    key.to_s.split('_').map do |part|
      "#{part[0,1].upcase}#{part[1,part.size]}"
    end.join.to_sym
  else
    if(_camel_keys)
      # Convert so Hash doesn't make a new one and lose the meta
      key = ::CamelString.new(key) unless key.is_a?(::CamelString)
    end
    key
  end
end

#_rootObject



307
308
309
310
311
312
313
# File 'lib/attribute_struct/attribute_struct.rb', line 307

def _root
  r = self
  until(r._parent.nil?)
    r = r._parent
  end
  r
end

#_set(key, val = nil, &block) ⇒ Object

key

Object

val

Object

Directly set val into struct. Useful when key is not valid syntax for a ruby method



74
75
76
77
78
79
80
# File 'lib/attribute_struct/attribute_struct.rb', line 74

def _set(key, val=nil, &block)
  if(val)
    self.method_missing(key, val, &block)
  else
    self.method_missing(key, &block)
  end
end

#is_a?(klass) ⇒ Boolean Also known as: kind_of?

klass

Class

Returns if this struct is a klass

Returns:

  • (Boolean)


142
143
144
# File 'lib/attribute_struct/attribute_struct.rb', line 142

def is_a?(klass)
  klass.ancestors.include?(_klass)
end

#nil?Boolean

Returns if this struct is considered nil (empty data)

Returns:

  • (Boolean)


136
137
138
# File 'lib/attribute_struct/attribute_struct.rb', line 136

def nil?
  _data.empty?
end