Class: VagrantCloud::Data::Immutable

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

Overview

Immutable data class. This class adds extra functionality to the Data class like providing attribute methods which can be defined using the ‘attr_required` and `attr_optional` methods. Once an instance is created the data is immutable. For example:

class MyData < Immutable

attr_required :name
attr_optional :version

end

When creating a new instance, a name parameter must be provided, but a version parameter is optional, so both are valid:

instance = MyData.new(name: “testing”, version: “new-version”)

and

instance = MyData.new(name: “testing”)

but only providing the version is invalid:

instance = MyData.new(version: “new-version”) # -> Exception

Direct Known Subclasses

Mutable, Response

Constant Summary collapse

@@lock =
Mutex.new

Constants inherited from VagrantCloud::Data

Nil

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from VagrantCloud::Data

#[]

Constructor Details

#initialize(**opts) ⇒ Immutable

Create a new instance



137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'lib/vagrant_cloud/data.rb', line 137

def initialize(**opts)
  super()
  self.class.attr_required.each do |attr|
    if !opts.key?(attr)
      raise ArgumentError, "Missing required parameter `#{attr}`"
    end
    data[attr.to_sym] = opts[attr].dup
  end
  self.class.attr_optional.each do |attr|
    if opts.key?(attr)
      data[attr.to_sym] = opts[attr].dup
    end
  end
  extras = opts.keys - (self.class.attr_required + self.class.attr_optional)
  if !extras.empty?
    raise ArgumentError, "Unknown parameters provided: #{extras.join(",")}"
  end
  freezer(@data)
end

Class Method Details

.attr_optional(*args) ⇒ Object

Define attributes which are optional



100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/vagrant_cloud/data.rb', line 100

def self.attr_optional(*args)
  return @optional || [] if args.empty?
  sync do
    @optional ||= []
    if !args.empty?
      # Create any accessor method which do not yet exist
      args = args.map(&:to_sym) - @optional
      args.each do |argument_name|
        if !method_defined?(argument_name)
          define_method(argument_name) {
            send(:[], argument_name.to_sym)
          }
        end
      end
      @optional += args
    end
    @optional
  end
end

.attr_required(*args) ⇒ Object

Define attributes which are required



79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/vagrant_cloud/data.rb', line 79

def self.attr_required(*args)
  return @required || [] if args.empty?
  sync do
    @required ||= []
    if !args.empty?
      # Create any accessor methods which do not yet exist
      args = args.map(&:to_sym) - @required
      args.each do |argument_name|
        if !method_defined?(argument_name)
          define_method(argument_name) {
            send(:[], argument_name.to_sym)
          }
        end
      end
      @required += args
    end
    @required
  end
end

.inherited(klass) ⇒ Object

If inherited, set attribute information



121
122
123
124
125
# File 'lib/vagrant_cloud/data.rb', line 121

def self.inherited(klass)
  klass.attr_required(*attr_required)
  klass.attr_optional(*attr_optional)
  klass.class_variable_set(:@@lock, Mutex.new)
end

.syncObject

Synchronize action



128
129
130
131
132
# File 'lib/vagrant_cloud/data.rb', line 128

def self.sync
  @@lock.synchronize do
    yield
  end
end

Instance Method Details

#inspectString

Returns:

  • (String)


158
159
160
161
162
163
164
165
# File 'lib/vagrant_cloud/data.rb', line 158

def inspect
  vars = (self.class.attr_required + self.class.attr_optional).map do |k|
    val = self.send(:[], k)
    next if val.nil? || val.to_s.empty?
    "#{k}=#{val.inspect}"
  end.compact.join(", ")
  "<#{self.class.name}:#{sprintf("%#x", object_id)} #{vars}>"
end