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:
-
VARIANT - Symbol name of the variant
-
MEMBERS - Array of Symbols which enumerate the variant's arguments
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