Class: SumsUp::Core::Variant
- Inherits:
-
Object
- Object
- SumsUp::Core::Variant
- Defined in:
- lib/sums_up/core/variant.rb
Overview
Represents a variant of a sumtype. Use build_variant_class to generate a new subclass for a given variant.
Class Method Summary collapse
- .accessors_module(members) ⇒ Object
- .build_variant_class(name, other_names, members, matcher_class) ⇒ Object
- .predicates_module(correct_name, incorrect_names) ⇒ Object
Instance Method Summary collapse
- #==(other) ⇒ Object
- #[](key) ⇒ Object
- #[]=(key, val) ⇒ Object
- #attributes ⇒ Object
-
#initialize(*values) ⇒ Variant
constructor
A new instance of Variant.
- #inspect ⇒ Object (also: #to_s)
- #match(**kwargs) ⇒ Object
- #members(dup: true) ⇒ Object (also: #to_a)
- #to_h(include_root: true) ⇒ Object
Constructor Details
#initialize(*values) ⇒ Variant
Returns a new instance of Variant.
42 43 44 45 46 47 48 49 50 51 52 53 54 |
# File 'lib/sums_up/core/variant.rb', line 42 def initialize(*values) given = values.length expected = self.class::MEMBERS.length if given != expected raise( ArgumentError, "wrong number of arguments (given #{given}, expected #{expected})" ) end @values = values end |
Class Method Details
.accessors_module(members) ⇒ Object
22 23 24 25 26 27 28 29 30 |
# File 'lib/sums_up/core/variant.rb', line 22 def self.accessors_module(members) Module.new do members.each_with_index do |member, idx| define_method(member) { @values[idx] } define_method(:"#{member}=") { |val| @values[idx] = val } end end end |
.build_variant_class(name, other_names, members, matcher_class) ⇒ Object
8 9 10 11 12 13 14 15 16 17 18 19 20 |
# File 'lib/sums_up/core/variant.rb', line 8 def self.build_variant_class(name, other_names, members, matcher_class) Class.new(self) do const_set(:VARIANT, name) const_set(:MEMBERS, members.freeze) const_set(:Accessors, accessors_module(members)) const_set(:Matcher, matcher_class) const_set(:Predicates, predicates_module(name, other_names)) include(const_get(:Accessors)) include(const_get(:Predicates)) end end |
.predicates_module(correct_name, incorrect_names) ⇒ Object
32 33 34 35 36 37 38 39 40 |
# File 'lib/sums_up/core/variant.rb', line 32 def self.predicates_module(correct_name, incorrect_names) Module.new do define_method(:"#{correct_name}?", &Functions.const(true)) incorrect_names.each do |incorrect_name| define_method(:"#{incorrect_name}?", &Functions.const(false)) end end end |
Instance Method Details
#==(other) ⇒ Object
121 122 123 124 |
# File 'lib/sums_up/core/variant.rb', line 121 def ==(other) other.is_a?(self.class) && (other.to_a(dup: false) == @values) end |
#[](key) ⇒ Object
56 57 58 59 60 |
# File 'lib/sums_up/core/variant.rb', line 56 def [](key) idx = index_for_key(key) @values[idx] end |
#[]=(key, val) ⇒ Object
62 63 64 65 66 |
# File 'lib/sums_up/core/variant.rb', line 62 def []=(key, val) idx = index_for_key(key) @values[idx] = val end |
#attributes ⇒ Object
90 91 92 |
# File 'lib/sums_up/core/variant.rb', line 90 def attributes self.class::MEMBERS.zip(@values).to_h end |
#inspect ⇒ Object Also known as: to_s
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
# File 'lib/sums_up/core/variant.rb', line 102 def inspect # If a sum type is defined but not assigned to a constant, Class.name # name will return nil in Ruby 2. variant = self.class.name || self.class::VARIANT attrs = self.class::MEMBERS .zip(@values) .map { |member, value| "#{member}=#{value.inspect}" } .join(", ") if attrs.empty? "#<variant #{variant}>" else "#<variant #{variant} #{attrs}>" end end |
#match(**kwargs) ⇒ Object
68 69 70 71 72 73 74 75 76 77 78 |
# File 'lib/sums_up/core/variant.rb', line 68 def match(**kwargs) matcher = self.class::Matcher.new(self) if block_given? yield(matcher) else matcher._match_hash(kwargs) end matcher._fetch_result end |
#members(dup: true) ⇒ Object Also known as: to_a
80 81 82 83 84 85 86 |
# File 'lib/sums_up/core/variant.rb', line 80 def members(dup: true) if dup @values.dup else @values end end |
#to_h(include_root: true) ⇒ Object
94 95 96 97 98 99 100 |
# File 'lib/sums_up/core/variant.rb', line 94 def to_h(include_root: true) if include_root {self.class::VARIANT => attributes} else attributes end end |