Class: VagrantCloud::Data::Mutable

Inherits:
Immutable show all
Defined in:
lib/vagrant_cloud/data.rb

Overview

Mutable data class

Direct Known Subclasses

Box, Box::Provider, Box::Version, Organization

Constant Summary

Constants inherited from VagrantCloud::Data

Nil

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Immutable

attr_optional, attr_required, inherited, #inspect, sync

Methods inherited from VagrantCloud::Data

#inspect

Constructor Details

#initialize(**opts) ⇒ Mutable

Create a new instance



217
218
219
220
# File 'lib/vagrant_cloud/data.rb', line 217

def initialize(**opts)
  super
  @dirty = {}
end

Class Method Details

.attr_mutable(*args) ⇒ Object

Define attributes which are mutable



187
188
189
190
191
192
193
194
195
196
# File 'lib/vagrant_cloud/data.rb', line 187

def self.attr_mutable(*args)
  sync do
    args.each do |attr|
      if !attr_required.include?(attr.to_sym) && !attr_optional.include?(attr.to_sym)
        raise ArgumentError, "Unknown attribute name provided `#{attr}`"
      end
      define_method("#{attr}=") { |v| dirty[attr.to_sym] = v }
    end
  end
end

.load(options = {}) ⇒ Mutable

Load data and create a new instance

Parameters:

  • options (Hash) (defaults to: {})

    Value to initialize instance

Returns:



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

def self.load(options={})
  opts = {}.tap do |o|
    (attr_required + attr_optional +
      self.instance_method(:initialize).parameters.find_all { |i|
      i.first == :key || i.first == :keyreq
    }.map(&:last)).each do |k|
      o[k.to_sym] = options[k.to_sym]
    end
  end
  self.new(**opts)
end

Instance Method Details

#[](k) ⇒ Object

Fetch value from data

Parameters:

  • k (String, Symbol)

    Name of value

Returns:

  • (Object)


226
227
228
229
230
231
232
# File 'lib/vagrant_cloud/data.rb', line 226

def [](k)
  if dirty?(k)
    @dirty[k.to_sym]
  else
    super
  end
end

#clean(data:, ignores: [], only: []) ⇒ self

Load given data and ignore any fields that are provided. Flush dirty state.

Parameters:

  • data (Hash)

    Attribute data to load

  • ignores (Array<Symbol>) (defaults to: [])

    Fields to skip

  • only (Array<Symbol>) (defaults to: [])

    Fields to update

Returns:

  • (self)

Raises:

  • (TypeError)


254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
# File 'lib/vagrant_cloud/data.rb', line 254

def clean(data:, ignores: [], only: [])
  raise TypeError, "Expected type `Hash` but received `#{data.inspect}`" if
    !data.is_a?(Hash)
  new_data = @data.dup
  ignores = Array(ignores).map(&:to_sym)
  only = Array(only).map(&:to_sym)
  data.each do |k, v|
    k = k.to_sym
    next if ignores.include?(k)
    next if !only.empty? && !only.include?(k)
    if self.respond_to?(k)
      new_data[k] = v
      @dirty.delete(k)
    end
  end
  @data = freezer(new_data)
  self
end

#clean!self

Merge values from dirty cache into data

Returns:

  • (self)


276
277
278
279
280
# File 'lib/vagrant_cloud/data.rb', line 276

def clean!
  @data = freezer(@data.merge(@dirty))
  @dirty.clear
  self
end

#dirty?(key = nil, **opts) ⇒ Boolean

Check if instance is dirty or specific attribute if key is provided

Parameters:

  • key (Symbol) (defaults to: nil)

    Key to check

Returns:

  • (Boolean)

    instance is dirty



239
240
241
242
243
244
245
# File 'lib/vagrant_cloud/data.rb', line 239

def dirty?(key=nil, **opts)
  if key.nil?
    !@dirty.empty?
  else
    @dirty.key?(key.to_sym)
  end
end

#freezeself

Returns disable freezing.

Returns:

  • (self)

    disable freezing



283
284
285
# File 'lib/vagrant_cloud/data.rb', line 283

def freeze
  self
end