class ContractedValue::Value

Public Class Methods

inherited(klass) click to toggle source
Calls superclass method
# File lib/contracted_value/core.rb, line 276
def inherited(klass)
  super

  klass.instance_variable_set(:@attribute_set, AttributeSet.new)
end
new(input_attr_values = {}) click to toggle source

rubocop:disable Metrics/CyclomaticComplexity rubocop:disable Metrics/AbcSize

# File lib/contracted_value/core.rb, line 219
def initialize(input_attr_values = {})
  input_attr_values_hash =
    case input_attr_values
    when ::Hash
      input_attr_values
    when Value
      input_attr_values.to_h
    else
      raise(
        Errors::InvalidInputType.new(
          input_attr_values,
        ),
      )
    end

  self.class.send(:attribute_set).each_attribute do |attribute|
    attr_value = attribute.extract_value(input_attr_values_hash)

    sometimes_frozen_attr_value =
      case attribute.refrigeration_mode
      when RefrigerationMode::Enum::DEEP
        # Use ice_nine for deep freezing
        ::IceNine.deep_freeze(attr_value)
      when RefrigerationMode::Enum::SHALLOW
        # No need to re-freeze
        attr_value.frozen? ? attr_value : attr_value.freeze
      when RefrigerationMode::Enum::NONE
        # No freezing
        attr_value
      else
        raise Errors::InvalidRefrigerationMode.new(
          refrigeration_mode,
        )
      end

    # Using symbol since attribute names are limited in number
    # An alternative would be using frozen string
    instance_variable_set(
      :"@#{attribute.name}",
      sometimes_frozen_attr_value,
    )
  end

  freeze
end

Private Class Methods

attribute( name, contract: ::Contracts::Builtin::Any, refrigeration_mode: RefrigerationMode::Enum::DEEP, default_value: Private::ATTR_DEFAULT_VALUE_ABSENT_VAL ) click to toggle source

@api

# File lib/contracted_value/core.rb, line 285
def attribute(
  name,
  contract: ::Contracts::Builtin::Any,
  refrigeration_mode: RefrigerationMode::Enum::DEEP,
  default_value: Private::ATTR_DEFAULT_VALUE_ABSENT_VAL
)

  attr = Attribute.new(
    name: name,
    contract: contract,
    refrigeration_mode: refrigeration_mode,
    default_value: default_value,
  )
  @attribute_set = @attribute_set.add(attr)

  attr_reader(name)
end
attribute_set() click to toggle source

@api private

# File lib/contracted_value/core.rb, line 313
def attribute_set
  # When the chain comes back to original class
  # (ContractedValue::Value)
  # @attribute_set would be nil
  super_attribute_set.merge(@attribute_set || AttributeSet.new)
end
super_attribute_set() click to toggle source

@api private

# File lib/contracted_value/core.rb, line 304
def super_attribute_set
  unless superclass.respond_to?(:attribute_set, true)
    return AttributeSet.new
  end

  superclass.send(:attribute_set)
end

Public Instance Methods

to_h() click to toggle source

rubocop:enable Metrics/AbcSize rubocop:enable Metrics/CyclomaticComplexity

# File lib/contracted_value/core.rb, line 267
def to_h
  self.class.send(:attribute_set).
    each_attribute.each_with_object({}) do |attribute, hash|
      hash[attribute.name] = instance_variable_get(:"@#{attribute.name}")
    end
end