class ContractValueObject
Constants
- VERSION
Attributes
error_presenter[W]
Public Class Methods
attributes(attributes = nil)
click to toggle source
# File lib/contract_value_object.rb, line 11 def attributes(attributes = nil) if attributes.nil? return @attributes if instance_variable_defined?(:@attributes) raise ArgumentError, 'Calling for attributes without having defined them.' end attr_accessor(*attributes.keys) attr_writers = attributes.keys.map { |attribute| :"#{attribute}=" } private *attr_writers @attributes = attributes end
defaults(defaults = nil)
click to toggle source
# File lib/contract_value_object.rb, line 25 def defaults(defaults = nil) return @defaults ||= {} if defaults.nil? unexpected_defaults = defaults.keys - attributes.keys unless unexpected_defaults.empty? raise ArgumentError, "Unexpected defaults are set: #{unexpected_defaults.map(&:to_s).join(', ')}" end non_optional = defaults.select do |attribute, _| !attributes.fetch(attribute).is_a?(Contracts::Optional) end raise ArgumentError, "Unexpected non-optional defaults: #{non_optional.keys.join(', ')}" unless non_optional.empty? @defaults = defaults end
error_presenter()
click to toggle source
# File lib/contract_value_object.rb, line 44 def error_presenter @error_presenter ||= self::ErrorFormatter.new end
new(**attributes)
click to toggle source
# File lib/contract_value_object.rb, line 50 def initialize(**attributes) error_presenter = self.class.error_presenter class_attributes = self.class.attributes defaults = self.class.defaults error_message_class = DefinitionError::ErrorMessage # determine attributes that were not passed in but should have been missing_attributes = class_attributes.keys - attributes.keys - defaults.keys missing_attribute_errors = missing_attributes.flat_map do |attribute| next([]) if class_attributes[attribute].is_a?(Contracts::Optional) error_message_class.new(attribute, error_presenter.missing(attribute, class_attributes.fetch(attribute))) end # determine extraneous attributes that should not have been passed in unexpected_attributes = attributes.keys - class_attributes.keys unexpected_attribute_errors = unexpected_attributes.map do |attribute| error_message_class.new(attribute, error_presenter.unexpected(attribute)) end # set attributes on the object and raise if they do not obey the contract setter_errors = defaults.merge(attributes).flat_map do |attribute, value| next([]) if unexpected_attributes.include?(attribute) begin contract = class_attributes.fetch(attribute) contract.within_opt_hash! if contract.is_a?(Contracts::Optional) # begin support customized setter send("#{attribute}=", value) set_value = instance_variable_get("@#{attribute}") # end support for customized setter if Contract.valid?(set_value, contract) [] else raise ArgumentError, error_presenter.contract_failure(attribute, set_value, contract) end rescue self.class::DefinitionError => error error_message_class.new(attribute, error.message.gsub("\n", "\n\t")) rescue StandardError => error error_message_class.new(attribute, error.message) end end errors = missing_attribute_errors + unexpected_attribute_errors + setter_errors return if errors.empty? raise DefinitionError, errors end
Public Instance Methods
==(other)
click to toggle source
Calls superclass method
# File lib/contract_value_object.rb, line 111 def ==(other) return super(other) unless self.class == other.class self.class.attributes.all? do |attribute, _type| public_send(attribute) == other.public_send(attribute) end end
Also aliased as: eql?
hash()
click to toggle source
treating contract value objects with the same values as the same object for hashes and sets
# File lib/contract_value_object.rb, line 107 def hash to_h.hash end
inspect()
click to toggle source
# File lib/contract_value_object.rb, line 121 def inspect "#{self.class} #{to_h.inspect}" end
to_h()
click to toggle source
# File lib/contract_value_object.rb, line 98 def to_h key_value_pairs = self.class.attributes.map do |attribute, _type| [attribute, public_send(attribute)] end key_value_pairs.to_h end