vector_number 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -5,12 +5,21 @@ class VectorNumber
5
5
  # Mostly modeled after {::Complex}.
6
6
  module Querying
7
7
  # Whether this VectorNumber can be considered strictly numeric, e.g. real or complex.
8
+ #
9
+ # @example
10
+ # VectorNumber[2].numeric? # => true
11
+ # VectorNumber[2, 3i].numeric? # => true
12
+ # VectorNumber[2, "a"].numeric? # => false
13
+ # VectorNumber[2, 3i].numeric?(1) # => false
14
+ #
8
15
  # @param dimensions [Integer] number of dimensions to consider "numeric"
9
16
  # - 0 — zero
10
17
  # - 1 — real number
11
18
  # - 2 — complex number, etc.
12
19
  # @return [Boolean]
13
20
  # @raise [ArgumentError] if +dimensions+ is negative
21
+ #
22
+ # @since 0.2.0
14
23
  def numeric?(dimensions = 2)
15
24
  raise ArgumentError, "`dimensions` must be non-negative" unless dimensions >= 0
16
25
 
@@ -18,64 +27,124 @@ class VectorNumber
18
27
  end
19
28
 
20
29
  # Whether this VectorNumber contains any non-numeric parts.
30
+ #
31
+ # @example
32
+ # VectorNumber[2].nonnumeric? # => false
33
+ # VectorNumber[2, 3i].nonnumeric? # => false
34
+ # VectorNumber[2, "a"].nonnumeric? # => true
35
+ # VectorNumber[2, 3i].nonnumeric?(1) # => true
36
+ #
21
37
  # @param (see #numeric?)
22
38
  # @return (see #numeric?)
23
39
  # @raise (see #numeric?)
24
- def nonnumeric?(dimensions = 2)
25
- raise ArgumentError, "`dimensions` must be non-negative" unless dimensions >= 0
26
-
27
- !numeric?(dimensions)
28
- end
40
+ #
41
+ # @since 0.2.1
42
+ def nonnumeric?(dimensions = 2) = !numeric?(dimensions)
29
43
 
30
44
  # Returns +true+ if all coefficients are finite, +false+ otherwise.
45
+ #
46
+ # @example
47
+ # VectorNumber[2].finite? # => true
48
+ # VectorNumber[Float::NAN].finite? # => false
49
+ # VectorNumber["a"].mult(Float::INFINITY).finite? # => false
50
+ #
31
51
  # @return [Boolean]
52
+ #
53
+ # @since 0.1.0
32
54
  def finite?
33
55
  all? { |_u, v| v.finite? }
34
56
  end
35
57
 
36
58
  # Returns +1+ if any coefficients are infinite, +nil+ otherwise.
59
+ #
60
+ # This behavior is the same as +Complex+'s.
61
+ #
62
+ # @example
63
+ # VectorNumber[2].infinite? # => nil
64
+ # VectorNumber[Float::NAN].infinite? # => 1
65
+ # VectorNumber["a"].mult(-Float::INFINITY).infinite? # => 1
66
+ #
37
67
  # @return [1, nil]
68
+ #
69
+ # @since 0.1.0
38
70
  def infinite?
39
71
  finite? ? nil : 1 # rubocop:disable Style/ReturnNilInPredicateMethodDefinition
40
72
  end
41
73
 
42
74
  # Returns +true+ if there are no non-zero coefficients, and +false+ otherwise.
75
+ #
76
+ # @example
77
+ # VectorNumber["c"].zero? # => false
78
+ # VectorNumber[].zero? # => true
79
+ #
43
80
  # @return [Boolean]
44
- def zero?
45
- size.zero?
46
- end
81
+ #
82
+ # @since 0.1.0
83
+ def zero? = size.zero?
47
84
 
48
85
  # Returns +self+ if there are any non-zero coefficients, +nil+ otherwise.
86
+ #
87
+ # This behavior is the same as +Numeric+'s.
88
+ #
89
+ # @example
90
+ # VectorNumber["ab", "cd"].nonzero? # => (1⋅'ab' + 1⋅'cd')
91
+ # VectorNumber[].nonzero? # => nil
92
+ #
49
93
  # @return [VectorNumber, nil]
94
+ #
95
+ # @since 0.1.0
50
96
  def nonzero?
51
97
  zero? ? nil : self # rubocop:disable Style/ReturnNilInPredicateMethodDefinition
52
98
  end
53
99
 
54
100
  # Returns +true+ if number is non-zero and all non-zero coefficients are positive,
55
101
  # and +false+ otherwise.
102
+ #
103
+ # @example
104
+ # VectorNumber["a"].positive? # => true
105
+ # VectorNumber[2].neg.positive? # => false
106
+ # (VectorNumber["1"] - VectorNumber[1]).positive? # => false
107
+ # VectorNumber[0].positive? # => false
108
+ #
56
109
  # @return [Boolean]
110
+ #
111
+ # @since 0.1.0
57
112
  def positive?
58
113
  !zero? && all? { |_u, c| c.positive? }
59
114
  end
60
115
 
61
116
  # Returns +true+ if number is non-zero and all non-zero coefficients are negative,
62
117
  # and +false+ otherwise.
118
+ #
119
+ # @example
120
+ # VectorNumber["a"].neg.negative? # => true
121
+ # VectorNumber[-2].neg.negative? # => false
122
+ # (VectorNumber["1"] - VectorNumber[1]).negative? # => false
123
+ # VectorNumber[0].negative? # => false
124
+ #
63
125
  # @return [Boolean]
126
+ #
127
+ # @since 0.1.0
64
128
  def negative?
65
129
  !zero? && all? { |_u, c| c.negative? }
66
130
  end
67
131
 
68
- # Always returns +false+, as vectors are never real numbers.
132
+ # Always returns +false+, as vectors are not real numbers.
133
+ #
134
+ # This behavior is the same as +Complex+'s.
135
+ #
69
136
  # @see #numeric?
137
+ #
70
138
  # @return [false]
71
- def real?
72
- false
73
- end
139
+ #
140
+ # @since 0.1.0
141
+ def real? = false
74
142
 
75
143
  # Always returns +false+, as vectors are not +Integer+s.
144
+ #
76
145
  # @return [false]
77
- def integer?
78
- false
79
- end
146
+ #
147
+ # @since 0.2.1
148
+ def integer? = false
80
149
  end
81
150
  end
@@ -4,21 +4,37 @@ class VectorNumber
4
4
  # Methods and options for string representation.
5
5
  module Stringifying
6
6
  # Predefined symbols for multiplication to display between unit and coefficient.
7
+ #
7
8
  # @return [Hash{Symbol => String}]
9
+ #
10
+ # @since 0.1.0
8
11
  MULT_STRINGS = {
9
12
  asterisk: "*", # U+002A
10
13
  cross: "×", # U+00D7
11
14
  dot: "⋅", # U+22C5
12
15
  invisible: "⁢", # U+2062, zero-width multiplication operator
13
16
  space: " ",
14
- none: ""
17
+ none: "",
15
18
  }.freeze
16
19
 
20
+ # Get a string representation of the vector.
21
+ #
22
+ # @example
23
+ # VectorNumber[5, "s"].to_s # => "5 + 1⋅'s'"
24
+ # VectorNumber["s", 5].to_s # => "1⋅'s' + 5"
25
+ # @example with :mult argument
26
+ # VectorNumber[5, "s"].to_s(mult: :asterisk) # => "5 + 1*'s'"
27
+ # @example :mult option specified for the vector
28
+ # VectorNumber[5, "s", mult: :none].to_s # => "5 + 1's'"
29
+ #
17
30
  # @param mult [Symbol, String]
18
31
  # text to use between coefficient and unit,
19
32
  # can be one of the keys in {MULT_STRINGS} or an arbitrary string
20
33
  # @return [String]
21
- # @raise [ArgumentError] if +mult+ is not in {MULT_STRINGS}'s keys
34
+ # @raise [ArgumentError]
35
+ # if +mult+ is not a String and is not in {MULT_STRINGS}'s keys
36
+ #
37
+ # @since 0.1.0
22
38
  def to_s(mult: options[:mult])
23
39
  return "0" if zero?
24
40
 
@@ -34,7 +50,18 @@ class VectorNumber
34
50
  result
35
51
  end
36
52
 
53
+ # Get a string representation of the vector.
54
+ #
55
+ # This is similar to +Complex#inspect+: it returns result of {#to_s} in round brackets.
56
+ #
57
+ # @example
58
+ # VectorNumber[5, "s"].inspect # => "(5 + 1⋅'s')"
59
+ #
37
60
  # @return [String]
61
+ #
62
+ # @see to_s
63
+ #
64
+ # @since 0.1.0
38
65
  def inspect
39
66
  # TODO: Probably make this independent of options.
40
67
  "(#{self})"
@@ -47,6 +74,8 @@ class VectorNumber
47
74
  # @param mult [Symbol, String]
48
75
  # @return [String]
49
76
  # @raise [ArgumentError] if +mult+ is not in {MULT_STRINGS}'s keys
77
+ #
78
+ # @since 0.1.0
50
79
  def value_to_s(unit, coefficient, mult:)
51
80
  if !mult.is_a?(String) && !MULT_STRINGS.key?(mult)
52
81
  raise ArgumentError, "unknown key #{mult.inspect}", caller
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- class VectorNumber # rubocop:disable Style/StaticClass
3
+ class VectorNumber
4
4
  # @return [String]
5
- VERSION = "0.3.0"
5
+ VERSION = "0.4.0"
6
6
  end
data/lib/vector_number.rb CHANGED
@@ -1,13 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "vector_number/version"
4
- require_relative "vector_number/mathing"
5
- require_relative "vector_number/math_converting"
3
+ require_relative "vector_number/comparing"
6
4
  require_relative "vector_number/converting"
7
5
  require_relative "vector_number/enumerating"
8
- require_relative "vector_number/comparing"
6
+ require_relative "vector_number/math_converting"
7
+ require_relative "vector_number/mathing"
9
8
  require_relative "vector_number/querying"
10
9
  require_relative "vector_number/stringifying"
10
+ require_relative "vector_number/version"
11
11
 
12
12
  # A class to add together anything.
13
13
  class VectorNumber
@@ -19,41 +19,87 @@ class VectorNumber
19
19
  include Querying
20
20
  include Stringifying
21
21
 
22
+ # Keys for possible options.
23
+ # Unknown options will be rejected when creating a vector.
24
+ #
22
25
  # @return [Array<Symbol>]
26
+ #
27
+ # @since 0.2.0
23
28
  KNOWN_OPTIONS = %i[mult].freeze
24
29
 
30
+ # Default values for options.
31
+ #
25
32
  # @return [Hash{Symbol => Object}]
33
+ #
34
+ # @since 0.2.0
26
35
  DEFAULT_OPTIONS = { mult: :dot }.freeze
27
36
 
28
37
  # Get a unit for +n+th numeric dimension, where 1 is real, 2 is imaginary.
29
- UNIT = ->(n) { (n - 1).i }.freeze
38
+ #
39
+ # @since 0.2.0
40
+ UNIT = ->(n) { n }.freeze
30
41
  # Constant for real unit.
42
+ #
43
+ # @since 0.2.0
31
44
  R = UNIT[1]
32
45
  # Constant for imaginary unit.
46
+ #
47
+ # @since 0.1.0
33
48
  I = UNIT[2]
34
49
 
35
- # Number of non-zero dimensions.
36
- # @return [Integer]
37
- attr_reader :size
38
- # @return [Hash{Symbol => Object}]
39
- attr_reader :options
40
-
41
- # Create new VectorNumber from +values+.
50
+ # Create new VectorNumber from a list of values, possibly specifying options.
42
51
  #
43
52
  # @example
44
- # VectorNumber[1, 2, 3] #=> (6)
45
- # VectorNumber[[1, 2, 3]] #=> (1⋅[1, 2, 3])
46
- # VectorNumber['b', VectorNumber::I, mult: :asterisk] #=> (1*'b' + 1i)
53
+ # VectorNumber[1, 2, 3] # => (6)
54
+ # VectorNumber[[1, 2, 3]] # => (1⋅[1, 2, 3])
55
+ # VectorNumber["b", VectorNumber::I, mult: :asterisk] # => (1*'b' + 1i)
56
+ # VectorNumber[] # => (0)
57
+ # VectorNumber["b", VectorNumber["b"]] # => (2⋅'b')
58
+ # VectorNumber["a", "b", "a"] # => (2⋅'a' + 1⋅'b')
59
+ #
47
60
  # @param values [Array<Object>] values to put in the number
48
61
  # @param options [Hash{Symbol => Object}] options for the number
62
+ # @option options [Symbol, String] :mult Multiplication symbol,
63
+ # either a key from {MULT_STRINGS} or a literal string to use
49
64
  # @return [VectorNumber]
65
+ #
66
+ # @since 0.1.0
50
67
  def self.[](*values, **options)
51
68
  new(values, options)
52
69
  end
53
70
 
54
- # @param values [Array, Hash{Object => Integer, Float, Rational, BigDecimal}, VectorNumber]
71
+ # Number of non-zero dimensions.
72
+ #
73
+ # @return [Integer]
74
+ #
75
+ # @since 0.1.0
76
+ attr_reader :size
77
+
78
+ # Options used for this vector.
79
+ #
80
+ # @see KNOWN_OPTIONS
81
+ #
82
+ # @return [Hash{Symbol => Object}]
83
+ #
84
+ # @since 0.1.0
85
+ attr_reader :options
86
+
87
+ # Create new VectorNumber from +values+, possibly specifying +options+,
88
+ # possibly modifying coefficients with a block.
89
+ #
90
+ # @example
91
+ # VectorNumber.new(1, 2, 3) # ArgumentError
92
+ # VectorNumber.new([1, 2, 3]) # => (6)
93
+ # VectorNumber.new(["b", VectorNumber::I], mult: :asterisk) # => (1*'b' + 1i)
94
+ # VectorNumber.new # => (0)
95
+ # @example with a block
96
+ # VectorNumber.new(["a", "b", "c", 3]) { _1 * 2 } # => (2⋅'a' + 2⋅'b' + 2⋅'c' + 6)
97
+ # VectorNumber.new(["a", "b", "c", 3], &:-@) # => (-1⋅'a' - 1⋅'b' - 1⋅'c' - 3)
98
+ # VectorNumber.new(["a", "b", "c", 3], &:digits) # RangeError
99
+ #
100
+ # @param values [Array, VectorNumber, Hash{Object => Integer, Float, Rational, BigDecimal}, nil]
55
101
  # values for this number, hashes are treated like plain vector numbers
56
- # @param options [Hash{Symbol => Object}]
102
+ # @param options [Hash{Symbol => Object}, nil]
57
103
  # options for this number, if +values+ is a VectorNumber or contains it,
58
104
  # these will be merged with options from its +options+
59
105
  # @option options [Symbol, String] :mult
@@ -62,7 +108,7 @@ class VectorNumber
62
108
  # @yieldreturn [Integer, Float, Rational, BigDecimal] new coefficient
63
109
  # @raise [RangeError] if any pesky non-reals get where they shouldn't
64
110
  def initialize(values = nil, options = nil, &)
65
- # @type var options: Hash[Symbol, Symbol]
111
+ # @type var options: Hash[Symbol, Object]
66
112
  initialize_from(values)
67
113
  apply_transform(&)
68
114
  finalize_contents
@@ -75,13 +121,18 @@ class VectorNumber
75
121
  # Return self.
76
122
  #
77
123
  # @return [VectorNumber]
78
- alias dup itself
124
+ #
125
+ # @since 0.2.0
126
+ def +@ = self
127
+ # @since 0.2.4
128
+ alias dup +@
79
129
 
80
130
  # Return self.
81
131
  #
82
- # Raises ArgumentError if +freeze+ is not +true+ or +nil+.
83
- #
84
132
  # @return [VectorNumber]
133
+ # @raise [ArgumentError] if +freeze+ is not +true+ or +nil+.
134
+ #
135
+ # @since 0.2.4
85
136
  def clone(freeze: true)
86
137
  case freeze
87
138
  when true, nil
@@ -96,6 +147,7 @@ class VectorNumber
96
147
  private
97
148
 
98
149
  # Create new VectorNumber from a value or self, optionally applying a transform.
150
+ #
99
151
  # @param from [Object] self if not specified
100
152
  # @yieldparam coefficient [Integer, Float, Rational, BigDecimal]
101
153
  # @yieldreturn [Integer, Float, Rational, BigDecimal] new coefficient
@@ -104,29 +156,42 @@ class VectorNumber
104
156
  self.class.new(from, options, &)
105
157
  end
106
158
 
159
+ # Check if +other+ is a real number.
160
+ #
161
+ # Currently this is either a +real?+ Numeric or +numeric?(1)+ VectorNumber.
162
+ #
107
163
  # @param value [Object]
108
164
  # @return [Boolean]
165
+ #
166
+ # @since 0.1.0
109
167
  def real_number?(value)
110
168
  (value.is_a?(Numeric) && value.real?) || (value.is_a?(self.class) && value.numeric?(1))
111
169
  end
112
170
 
113
171
  # @param values [Array, Hash{Object => Integer, Float, Rational, BigDecimal}, VectorNumber, nil]
114
172
  # @return [void]
173
+ #
174
+ # @since 0.1.0
115
175
  def initialize_from(values)
116
- @data = Hash.new(0)
176
+ @data = values.to_h and return if values.is_a?(VectorNumber)
117
177
 
178
+ @data = Hash.new(0)
118
179
  case values
119
- when VectorNumber, Hash
120
- add_vector_to_data(values)
121
180
  when Array
122
181
  values.each { |value| add_value_to_data(value) }
182
+ when Hash
183
+ add_vector_to_data(values)
184
+ when nil
185
+ # Do nothing, as there are no values.
123
186
  else
124
- # Don't add anything.
187
+ raise ArgumentError, "unsupported type for values: #{values.class}"
125
188
  end
126
189
  end
127
190
 
128
191
  # @param value [VectorNumber, Numeric, Object]
129
192
  # @return [void]
193
+ #
194
+ # @since 0.1.0
130
195
  def add_value_to_data(value)
131
196
  case value
132
197
  when Numeric
@@ -140,13 +205,19 @@ class VectorNumber
140
205
 
141
206
  # @param value [Numeric]
142
207
  # @return [void]
208
+ #
209
+ # @since 0.1.0
143
210
  def add_numeric_value_to_data(value)
144
211
  @data[R] += value.real
145
- @data[I] += value.imaginary
212
+ # Most numbers will be real, and this extra condition appreciably speeds up addition,
213
+ # while having no noticeable impact on complex numbers.
214
+ @data[I] += value.imaginary unless value.real?
146
215
  end
147
216
 
148
217
  # @param vector [VectorNumber, Hash{Object => Integer, Float, Rational, BigDecimal}]
149
218
  # @return [void]
219
+ #
220
+ # @since 0.1.0
150
221
  def add_vector_to_data(vector)
151
222
  vector.each_pair do |unit, coefficient|
152
223
  raise RangeError, "#{coefficient} is not a real number" unless real_number?(coefficient)
@@ -159,6 +230,8 @@ class VectorNumber
159
230
  # @yieldreturn [Integer, Float, Rational, BigDecimal]
160
231
  # @return [void]
161
232
  # @raise [RangeError]
233
+ #
234
+ # @since 0.1.0
162
235
  def apply_transform
163
236
  return unless block_given?
164
237
 
@@ -173,44 +246,40 @@ class VectorNumber
173
246
  # @param options [Hash{Symbol => Object}, nil]
174
247
  # @param values [Object] initializing object
175
248
  # @return [void]
249
+ #
250
+ # @since 0.1.0
176
251
  def save_options(options, values:)
177
252
  @options =
178
- case [options, values]
179
- in [{} | nil, VectorNumber]
180
- values.options
181
- in [{} | nil, [*, VectorNumber => vector, *]]
182
- vector.options
183
- in Hash, VectorNumber
253
+ case values
254
+ in VectorNumber
184
255
  merge_options(values.options, options)
185
- in Hash, [*, VectorNumber => vector, *]
256
+ in Array[*, VectorNumber => vector, *]
186
257
  merge_options(vector.options, options)
187
- in Hash, _ unless options.empty?
188
- merge_options(default_options, options)
189
258
  else
190
- default_options
259
+ merge_options(DEFAULT_OPTIONS, options)
191
260
  end
192
261
  end
193
262
 
263
+ # @param base_options [Hash{Symbol => Object}]
264
+ # @param added_options [Hash{Symbol => Object}, nil]
265
+ # @return [Hash{Symbol => Object}]
266
+ #
267
+ # @since 0.3.0
194
268
  def merge_options(base_options, added_options)
269
+ return base_options if !added_options || added_options.empty?
195
270
  # Optimization for the common case of passing options through #new.
196
271
  return base_options if added_options.equal?(base_options)
197
272
 
198
- base_options.merge(added_options).slice(*known_options)
273
+ base_options.merge(added_options).slice(*KNOWN_OPTIONS)
199
274
  end
200
275
 
201
276
  # Compact coefficients, calculate size and freeze data.
202
277
  # @return [void]
278
+ #
279
+ # @since 0.1.0
203
280
  def finalize_contents
204
281
  @data.delete_if { |_u, c| c.zero? }
205
282
  @data.freeze
206
283
  @size = @data.size
207
284
  end
208
-
209
- def default_options
210
- DEFAULT_OPTIONS
211
- end
212
-
213
- def known_options
214
- KNOWN_OPTIONS
215
- end
216
285
  end
@@ -55,7 +55,8 @@ class VectorNumber
55
55
  ?{ (coefficient_type coefficient) -> coefficient_type }
56
56
  -> void
57
57
 
58
- def dup: () -> self
58
+ def +@: () -> self
59
+ alias dup +@
59
60
 
60
61
  def clone: (?freeze: bool?) -> self
61
62
 
@@ -76,6 +77,7 @@ class VectorNumber
76
77
  def apply_transform: () ?{ (coefficient_type value) -> coefficient_type } -> void
77
78
 
78
79
  def save_options: (options_type? options, values: in_value_type) -> void
80
+ def merge_options: (options_type base_options, options_type added_options) -> options_type
79
81
  def default_options: () -> options_type
80
82
  def known_options: () -> list[Symbol]
81
83
 
@@ -87,8 +89,6 @@ class VectorNumber
87
89
 
88
90
  def coerce: (in_value_type) -> [vector_type, self]
89
91
 
90
- def +@: () -> self
91
-
92
92
  def -@: () -> vector_type
93
93
  alias neg -@
94
94
 
metadata CHANGED
@@ -1,21 +1,26 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vector_number
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alexandr Bulancov
8
+ autorequire:
8
9
  bindir: exe
9
10
  cert_chain: []
10
- date: 2025-05-12 00:00:00.000000000 Z
11
+ date: 2025-07-07 00:00:00.000000000 Z
11
12
  dependencies: []
13
+ description:
14
+ email:
12
15
  executables: []
13
16
  extensions: []
14
17
  extra_rdoc_files:
15
18
  - README.md
16
19
  - CHANGELOG.md
20
+ - LICENSE.txt
17
21
  files:
18
22
  - CHANGELOG.md
23
+ - LICENSE.txt
19
24
  - README.md
20
25
  - lib/vector_number.rb
21
26
  - lib/vector_number/comparing.rb
@@ -33,12 +38,17 @@ licenses:
33
38
  - MIT
34
39
  metadata:
35
40
  homepage_uri: https://github.com/trinistr/vector_number
36
- source_code_uri: https://github.com/trinistr/vector_number
37
- changelog_uri: https://github.com/trinistr/vector_number/CHANGELOG.md
41
+ bug_tracker_uri: https://github.com/trinistr/vector_number/issues
42
+ documentation_uri: https://rubydoc.info/gems/vector_number/0.4.0
43
+ source_code_uri: https://github.com/trinistr/vector_number/tree/v0.4.0
44
+ changelog_uri: https://github.com/trinistr/vector_number/blob/v0.4.0/CHANGELOG.md
38
45
  rubygems_mfa_required: 'true'
46
+ post_install_message:
39
47
  rdoc_options:
40
48
  - "--main"
41
49
  - README.md
50
+ - "--files"
51
+ - CHANGELOG.md,LICENSE.txt
42
52
  require_paths:
43
53
  - lib
44
54
  required_ruby_version: !ruby/object:Gem::Requirement
@@ -52,7 +62,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
52
62
  - !ruby/object:Gem::Version
53
63
  version: '0'
54
64
  requirements: []
55
- rubygems_version: 3.6.5
65
+ rubygems_version: 3.4.19
66
+ signing_key:
56
67
  specification_version: 4
57
68
  summary: A library to add together anything.
58
69
  test_files: []