class VagrantCloud::Data::Immutable
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
Public Class Methods
Define attributes which are optional
# 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
Define attributes which are required
# 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
If inherited, set attribute information
# 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
Create a new instance
@return [Immutable]
VagrantCloud::Data::new
# 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
Synchronize action
# File lib/vagrant_cloud/data.rb, line 128 def self.sync @@lock.synchronize do yield end end
Public Instance Methods
@return [String]
# 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
Protected Instance Methods
Freeze the given object and all nested objects that can be found
@return [Object]
# File lib/vagrant_cloud/data.rb, line 173 def freezer(obj) if obj.is_a?(Enumerable) obj.each do |item| freezer(item) item.freeze end end obj.freeze end