class SumsUp::Core::SumType

SumTypes are just modules with a meta-programmed methods to construct variants. Use SumType.build to define a new one.

Each variant class must have the following constants defined:

Public Class Methods

build(variant_classes) click to toggle source
# File lib/sums_up/core/sum_type.rb, line 16
def self.build(variant_classes)
  new do
    const_set(:VARIANTS, variant_classes.freeze)

    variant_classes.each do |variant_class|
      variant_name = variant_class.const_get(:VARIANT)
      class_name = SumType.variant_class_name(variant_name)
      initializer = SumType.variant_initializer(variant_class)

      const_set(class_name, variant_class)
      define_singleton_method(variant_name, &initializer)

      variant_class.include(self)
    end
  end
end
dup_if_overridden(frozen) click to toggle source
# File lib/sums_up/core/sum_type.rb, line 58
def self.dup_if_overridden(frozen)
  proc do |memo: true|
    memo ? frozen : frozen.dup
  end
end
variant_class_name(variant_name) click to toggle source
# File lib/sums_up/core/sum_type.rb, line 33
def self.variant_class_name(variant_name)
  Strings
    .snake_to_class(variant_name.to_s)
    .to_sym
end
variant_initializer(variant_class) click to toggle source

Variants without any members are frozen by default for performance. Pass `memo: false` to its initializer to opt out of this behavior:

Maybe = SumsUp.define(:nothing, just: :value)

frozen_nothing = Maybe.nothing
unfrozen_nothing = Maybe.nothing(memo: false)

# Variants with members are never frozen.
unfrozen_just = Maybe.just(1)
# File lib/sums_up/core/sum_type.rb, line 50
def self.variant_initializer(variant_class)
  if variant_class.const_get(:MEMBERS).empty?
    dup_if_overridden(variant_class.new.freeze)
  else
    variant_class.method(:new)
  end
end