versionaire 8.6.0 → 9.2.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '086f0f72812f1c6dd5ae1597a8098c53513642ba6b642009dc7d33309dc87b84'
4
- data.tar.gz: daad3d46b8ccd0528fe9def4a0b4bd83b6b99810b909076150edce0fe6e8efcd
3
+ metadata.gz: d1e1e12933915ebaa8ce2769bac22f1ead28d07902b32bcdb4801f70b724b016
4
+ data.tar.gz: 4c454f8f399df43ebc649010c50d9ee95f321435c96468162ab21b9abd849abb
5
5
  SHA512:
6
- metadata.gz: 7958a758fc0d40c359f26a21c3f6eb9bbaf778b8dbfe82b9f798f15b5bfd5333ca1275554ea908a76a35539408578a8c9025386b14379983788e8d1ebdd47222
7
- data.tar.gz: 8646bfa7633a29cf08a75231df02eb55fc04f8d0ef8fc7b7c1e77b2361b8967f508ea2caa1444367e0d3fd683537babf14d2338773965a3a17c1d5ea272fffd2
6
+ metadata.gz: facb53e495986112920ca938387be6448eb5bd6e6b94d1a8d5a5e3f3a9c34bbed72da9b6d2f0476b052796d61bedbbb1f27553c536792d2b72a9f81e961d4f70
7
+ data.tar.gz: 32ad27fbdd19b4c6d253009c025b9409ee29766f2eb0c7e158f5d2e231052b8efa661886a534c719cc0baef9b74758698831c81e49c1f7fd93d264ae7e3ffa33
checksums.yaml.gz.sig CHANGED
Binary file
data.tar.gz.sig CHANGED
Binary file
data/README.adoc CHANGED
@@ -128,7 +128,7 @@ Versionaire::Version version
128
128
  ----
129
129
 
130
130
  Each of these conversions will result in a version object that represents "`1.0.0`". When attempting
131
- to convert an unsupported type, a `+Versionaire::Errors::Conversion+` exception will be thrown.
131
+ to convert an unsupported type, a `+Versionaire::Errors::Cast+` exception will be thrown.
132
132
 
133
133
  ==== Refinement
134
134
 
@@ -159,7 +159,7 @@ Implicit conversion to a `+String+` is supported:
159
159
 
160
160
  [source,ruby]
161
161
  ----
162
- "1.0.0".match Versionaire::Version[major: 1] # <MatchData "1.0.0">
162
+ "1.0.0".match Versionaire::Version[major: 1] # <MatchData "1.0.0">
163
163
  ----
164
164
 
165
165
  ==== Explicit
@@ -170,9 +170,9 @@ Explicit conversion to a `String`, `Array`, or `Hash` is supported:
170
170
  ----
171
171
  version = Versionaire::Version.new
172
172
 
173
- version.to_s # "0.0.0"
174
- version.to_a # [0, 0, 0]
175
- version.to_h # {major: 0, minor: 0, patch: 0}
173
+ version.to_s # "0.0.0"
174
+ version.to_a # [0, 0, 0]
175
+ version.to_h # {major: 0, minor: 0, patch: 0}
176
176
  ----
177
177
 
178
178
  === Comparisons
@@ -185,41 +185,118 @@ work. Example:
185
185
  version_1 = Versionaire::Version "1.0.0"
186
186
  version_2 = Versionaire::Version "2.0.0"
187
187
 
188
- version_1 < version_2 # true
189
- version_1 <= version_2 # true
190
- version_1 == version_2 # false (see Equality section above for details)
191
- version_1 > version_2 # false
192
- version_1 >= version_2 # false
193
- version_1.between? version_1, version_2 # true
194
- version_1.clamp version_1, version_2 # version_1 (added in Ruby 2.4.0)
188
+ version_1 < version_2 # true
189
+ version_1 <= version_2 # true
190
+ version_1 == version_2 # false (see Equality section above for details)
191
+ version_1 > version_2 # false
192
+ version_1 >= version_2 # false
193
+ version_1.between? version_1, version_2 # true
194
+ version_1.clamp version_1, version_2 # version_1 (added in Ruby 2.4.0)
195
195
  ----
196
196
 
197
197
  === Math
198
198
 
199
- Versions can be added and subtracted from each other.
199
+ Versions can be added, subtracted, sequentially increased, or sequentially decreased from each
200
+ other.
200
201
 
201
202
  ==== Addition
202
203
 
204
+ Versions can be added together to produce a resulting version sum.
205
+
203
206
  [source,ruby]
204
207
  ----
205
208
  version_1 = Versionaire::Version[major: 1, minor: 2, patch: 3]
206
209
  version_2 = Versionaire::Version[major: 2, minor: 5, patch: 7]
207
- version_1 + version_2 # "3.7.10"
210
+ version_1 + version_2 # "3.7.10"
208
211
  ----
209
212
 
210
213
  ==== Subtraction
211
214
 
215
+ Versions can be substracted from each other as long as there isn't a negative result.
216
+
212
217
  [source,ruby]
213
218
  ----
214
219
  version_1 = Versionaire::Version[major: 1, minor: 2, patch: 3]
215
220
  version_2 = Versionaire::Version[major: 1, minor: 1, patch: 1]
216
- version_1 - version_2 # "0.1.2"
221
+ version_1 - version_2 # "0.1.2"
217
222
 
218
223
  version_1 = Versionaire::Version[major: 1]
219
224
  version_2 = Versionaire::Version[major: 5]
220
- version_1 - version_2 # Fails with a Versionaire::Errors::NegativeNumber
225
+ version_1 - version_2 # Versionaire::Errors::NegativeNumber
226
+ ----
227
+
228
+ ==== Up
229
+
230
+ Versions can be sequentially increased or given a specific version to jump to.
231
+
232
+ [source,ruby]
233
+ ----
234
+ version = Versionaire::Version[major: 1, minor: 1, patch: 1]
235
+ version.up :major # => "2.1.1"
236
+ version.up :major, 3 # => "4.1.1"
237
+ version.up :minor # => "1.2.1"
238
+ version.up :minor, 3 # => "1.4.1"
239
+ version.up :patch # => "1.1.2"
240
+ version.up :patch, 3 # => "1.1.4"
241
+ ----
242
+
243
+ ==== Down
244
+
245
+ Versions can be sequentially decreased or given a specific version to jump to as long as the result
246
+ is not negative.
247
+
248
+ [source,ruby]
249
+ ----
250
+ version = Versionaire::Version[major: 5, minor: 5, patch: 5]
251
+ version.down :major # => "4.5.5"
252
+ version.down :major, 3 # => "2.5.5"
253
+ version.down :minor # => "5.4.5"
254
+ version.down :minor, 3 # => "5.2.5"
255
+ version.down :patch # => "5.5.4"
256
+ version.down :patch, 3 # => "5.5.2"
257
+ version.down :major, 6 # => Versionaire::Errors::NegativeNumber
221
258
  ----
222
259
 
260
+ === Extensions
261
+
262
+ This project supports libraries which might desire native `Version` types. Each extension _must be
263
+ explicitly required_ in order to be used since they are _optional_ by default. See below for
264
+ details.
265
+
266
+ ==== OptionParser
267
+
268
+ link:https://github.com/ruby/optparse[OptionParser] is one of Ruby's
269
+ link:https://stdgems.org[default gems] which can accept additional types not native to Ruby by
270
+ default. To extend `OptionParser` with the `Version` type, all you need to do is add these two lines
271
+ to your implementation:
272
+
273
+ . `require "versionaire/extensions/option_parser"` - This will load dependencies and register the
274
+ `Version` type with `OptionParser`.
275
+ . `instance.on "--tag VERSION", Versionaire::Version` - Specifying `Versionaire::Version` as the
276
+ second argument will ensure `OptionParser` properly casts command line input as a `Version` type.
277
+
278
+ Here's an example implementation that demonstrates full usage:
279
+
280
+ [source,ruby]
281
+ ----
282
+ require "versionaire/extensions/option_parser"
283
+
284
+ options = {}
285
+
286
+ parser = OptionParser.new do |instance|
287
+ instance.on "--tag VERSION", Versionaire::Version, "Casts to version." do |value|
288
+ options[:version] = value
289
+ end
290
+ end
291
+
292
+ parser.parse! %w[--tag 1.2.3]
293
+ puts options
294
+ ----
295
+
296
+ The above will ensure `--tag 1.2.3` is parsed as `{:version=>#<struct Versionaire::Version major=1,
297
+ minor=2, patch=3>}` within your `options` variable. Should `OptionParser` parse an invalid version,
298
+ you'll get a `OptionParser::InvalidArgument` instead.
299
+
223
300
  == Development
224
301
 
225
302
  To contribute, run:
data/lib/versionaire.rb CHANGED
@@ -1,11 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "versionaire/identity"
3
4
  require "versionaire/errors/base"
4
- require "versionaire/errors/conversion"
5
+ require "versionaire/errors/cast"
5
6
  require "versionaire/errors/invalid_number"
6
7
  require "versionaire/errors/negative_number"
7
- require "versionaire/filler"
8
- require "versionaire/conversion"
9
- require "versionaire/identity"
10
8
  require "versionaire/version"
9
+ require "versionaire/function"
11
10
  require "versionaire/cast"
@@ -4,9 +4,7 @@ module Versionaire
4
4
  # Refines Kernel in order to provide a top-level Version conversion function.
5
5
  module Cast
6
6
  refine Kernel do
7
- def Version object
8
- Versionaire::Version object
9
- end
7
+ def Version(object) = Versionaire::Version(object)
10
8
  end
11
9
  end
12
10
  end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Versionaire
4
+ module Errors
5
+ # Thrown when attempting to cast an invalid primitive to a version.
6
+ class Cast < Base
7
+ end
8
+ end
9
+ end
@@ -4,9 +4,7 @@ module Versionaire
4
4
  module Errors
5
5
  # Thrown when not using numbers.
6
6
  class InvalidNumber < Base
7
- def initialize message = "Major, minor, and patch must be a number."
8
- super message
9
- end
7
+ def initialize(message = "Major, minor, and patch must be a number.") = super(message)
10
8
  end
11
9
  end
12
10
  end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "optparse"
4
+ require "versionaire"
5
+
6
+ OptionParser.accept Versionaire::Version do |value|
7
+ Versionaire::Version value
8
+ rescue Versionaire::Errors::Base
9
+ raise OptionParser::InvalidArgument, value
10
+ end
@@ -1,5 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "refinements/arrays"
4
+ require "refinements/structs"
5
+
3
6
  # The gem namespace.
4
7
  module Versionaire
5
8
  module_function
@@ -20,59 +23,53 @@ module Versionaire
20
23
 
21
24
  # Aids with converting objects into valid versions.
22
25
  class Converter
23
- def initialize object, filler: Filler.new
26
+ using Refinements::Arrays
27
+ using Refinements::Structs
28
+
29
+ def initialize object
24
30
  @object = object
25
- @filler = filler
26
31
  end
27
32
 
28
33
  def from_string
29
34
  body = "Use: <major>.<minor>.<patch>, <major>.<minor>, <major>, or empty string."
30
- fail Errors::Conversion, error_message(object, body) unless Version.regex.match? object
35
+ fail Errors::Cast, error_message(object, body) unless Version.pattern.match? object
31
36
 
32
- Version[**string_to_arguments]
37
+ string_to_version
33
38
  end
34
39
 
35
40
  def from_array
36
41
  body = "Use: [<major>, <minor>, <patch>], [<major>, <minor>], [<major>], or []."
37
- fail Errors::Conversion, error_message(object, body) unless (0..3).cover? object.size
42
+ fail Errors::Cast, error_message(object, body) unless (0..3).cover? object.size
38
43
 
39
- Version[**array_to_arguments]
44
+ Version.with_positions(*object.pad(0, max: 3))
40
45
  end
41
46
 
42
47
  def from_hash
43
48
  body = "Use: {major: <major>, minor: <minor>, patch: <patch>}, " \
44
49
  "{major: <major>, minor: <minor>}, {major: <major>}, or {}."
45
- fail Errors::Conversion, error_message(object, body) unless required_keys?
50
+ fail Errors::Cast, error_message(object, body) unless required_keys?
46
51
 
47
52
  Version[**object]
48
53
  end
49
54
 
50
55
  def from_object
51
- fail Errors::Conversion, error_message(object, "Use: String, Array, Hash, or Version.")
56
+ fail Errors::Cast, error_message(object, "Use: String, Array, Hash, or Version.")
52
57
  end
53
58
 
54
59
  private
55
60
 
56
61
  attr_reader :object, :filler
57
62
 
58
- def string_to_arguments
59
- object.split(DELIMITER)
63
+ def string_to_version
64
+ object.split(Version.delimiter)
60
65
  .map(&:to_i)
61
- .then { |numbers| filler.call numbers }
62
- .then { |arguments| Version.arguments(*arguments) }
63
- end
64
-
65
- def array_to_arguments
66
- Version.arguments(*filler.call(object))
66
+ .then { |numbers| numbers.pad 0, max: 3 }
67
+ .then { |arguments| Version.with_positions(*arguments) }
67
68
  end
68
69
 
69
- def required_keys?
70
- object.keys.all? { |key| Version.members.include? key }
71
- end
70
+ def required_keys? = object.keys.all? { |key| Version.members.include? key }
72
71
 
73
- def error_message object, body
74
- "Invalid version conversion: #{object}. #{body}"
75
- end
72
+ def error_message(object, body) = "Invalid version conversion: #{object}. #{body}"
76
73
  end
77
74
 
78
75
  private_constant :Converter
@@ -5,7 +5,7 @@ module Versionaire
5
5
  module Identity
6
6
  NAME = "versionaire"
7
7
  LABEL = "Versionaire"
8
- VERSION = "8.6.0"
8
+ VERSION = "9.2.0"
9
9
  VERSION_LABEL = "#{LABEL} #{VERSION}"
10
10
  end
11
11
  end
@@ -1,41 +1,45 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Versionaire
4
- DELIMITER = "."
3
+ require "refinements/structs"
5
4
 
5
+ module Versionaire
6
6
  # An immutable, semantic version value object.
7
7
  Version = Struct.new :major, :minor, :patch, keyword_init: true do
8
8
  include Comparable
9
9
 
10
- def self.regex
10
+ using Refinements::Structs
11
+
12
+ def self.delimiter = "."
13
+
14
+ def self.pattern
11
15
  /
12
16
  \A( # Start of string and OR.
13
17
  \d* # Major only.
14
18
  | # OR pipe.
15
19
  \d+ # Major.
16
- #{DELIMITER}? # Delimiter.
20
+ #{delimiter}? # Delimiter.
17
21
  \d* # Minor.
18
- (?:#{DELIMITER}\d+) # Passive delimiter and patch.
22
+ (?:#{delimiter}\d+) # Passive delimiter and patch.
19
23
  )\z # End of OR and string.
20
24
  /x
21
25
  end
22
26
 
23
- def self.arguments major, minor, patch
24
- Hash[members.zip [major, minor, patch]]
25
- end
26
-
27
27
  def initialize major: 0, minor: 0, patch: 0
28
28
  super
29
29
  validate
30
30
  freeze
31
31
  end
32
32
 
33
+ def []= key, value
34
+ super(key, value).tap { validate }
35
+ end
36
+
33
37
  def + other
34
- self.class.then { |klass| klass.new(**klass.arguments(*reduce(other, :+))) }
38
+ revalue(other.to_h) { |previous, current| previous + current }
35
39
  end
36
40
 
37
41
  def - other
38
- self.class.then { |klass| klass.new(**klass.arguments(*reduce(other, :-))) }
42
+ revalue(other.to_h) { |previous, current| previous - current }
39
43
  end
40
44
 
41
45
  def == other
@@ -48,15 +52,14 @@ module Versionaire
48
52
  to_s <=> other.to_s
49
53
  end
50
54
 
51
- def to_s
52
- to_a.join DELIMITER
53
- end
55
+ def down(key, value = 1) = revalue(key => value) { |previous, current| previous - current }
54
56
 
55
- alias_method :to_str, :to_s
57
+ def up(key, value = 1) = revalue(key => value) { |previous, current| previous + current }
56
58
 
57
- def to_a
58
- [major, minor, patch]
59
- end
59
+ def to_s = to_a.join(self.class.delimiter)
60
+
61
+ alias_method :to_str, :to_s
62
+ alias_method :values, :to_a
60
63
 
61
64
  private
62
65
 
@@ -64,9 +67,5 @@ module Versionaire
64
67
  fail Errors::InvalidNumber if to_a.any? { |number| !number.is_a? Integer }
65
68
  fail Errors::NegativeNumber if to_a.any?(&:negative?)
66
69
  end
67
-
68
- def reduce other, action
69
- to_a.zip(other.to_a).map { |pair| pair.reduce action }
70
- end
71
70
  end
72
71
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: versionaire
3
3
  version: !ruby/object:Gem::Version
4
- version: 8.6.0
4
+ version: 9.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brooke Kuhlmann
@@ -10,9 +10,9 @@ bindir: bin
10
10
  cert_chain:
11
11
  - |
12
12
  -----BEGIN CERTIFICATE-----
13
- MIIC/jCCAeagAwIBAgIBAzANBgkqhkiG9w0BAQsFADAlMSMwIQYDVQQDDBpicm9v
14
- a2UvREM9YWxjaGVtaXN0cy9EQz1pbzAeFw0yMDAzMTUxNDQ1MzJaFw0yMTAzMTUx
15
- NDQ1MzJaMCUxIzAhBgNVBAMMGmJyb29rZS9EQz1hbGNoZW1pc3RzL0RDPWlvMIIB
13
+ MIIC/jCCAeagAwIBAgIBBDANBgkqhkiG9w0BAQsFADAlMSMwIQYDVQQDDBpicm9v
14
+ a2UvREM9YWxjaGVtaXN0cy9EQz1pbzAeFw0yMTAzMTkxMjQ4MDZaFw0yMjAzMTkx
15
+ MjQ4MDZaMCUxIzAhBgNVBAMMGmJyb29rZS9EQz1hbGNoZW1pc3RzL0RDPWlvMIIB
16
16
  IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6l1qpXTiomH1RfMRloyw7MiE
17
17
  xyVx/x8Yc3EupdH7uhNaTXQGyORN6aOY//1QXXMHIZ9tW74nZLhesWMSUMYy0XhB
18
18
  brs+KkurHnc9FnEJAbG7ebGvl/ncqZt72nQvaxpDxvuCBHgJAz+8i5wl6FhLw+oT
@@ -20,16 +20,30 @@ cert_chain:
20
20
  D5vkU0YlAm1r98BymuJlcQ1qdkVEI1d48ph4kcS0S0nv1RiuyVb6TCAR3Nu3VaVq
21
21
  3fPzZKJLZBx67UvXdbdicWPiUR75elI4PXpLIic3xytaF52ZJYyKZCNZJhNwfQID
22
22
  AQABozkwNzAJBgNVHRMEAjAAMAsGA1UdDwQEAwIEsDAdBgNVHQ4EFgQU0nzow9vc
23
- 2CdikiiE3fJhP/gY4ggwDQYJKoZIhvcNAQELBQADggEBAIHhAlD3po4sTYqacXaQ
24
- XI9jIhrfMy//2PgbHWcETtlJPBeNUbbSNBABcllUHKqYsVDlSvSmss034KSWNR8F
25
- bF1GcloicyvcCC4y6IoW4it0COAcdeaaxkxiBSgKdQFpff9REnDlIKK4uQ9lLxIo
26
- Y2G5xubiziKZkyfWFuSr67PIjW3Bu673D1JVBArhA1qbgQmYQcy1CkGOjo+iO8Nf
27
- 7u/QSfBHb+r/bXhKscDgPpnKwbUmvgO2+94zJG9KsrmIydlzYfsD09aXKx0t6Xy4
28
- 2XV8FRa7/JimI07sPLC13eLY3xd/aYTi85Z782KIA4j0G8XEEWAX0ouBhlXPocZv
29
- QWc=
23
+ 2CdikiiE3fJhP/gY4ggwDQYJKoZIhvcNAQELBQADggEBAEjpaOXHHp8s/7GL2qCb
24
+ YAs7urOLv9VHSPfQWAwaTMVnSsIf3Sw4xzISOP/mmfEPBPXtz61K5esrE/uTFtgb
25
+ FyjxQk2H0sEWgrRXGGNHBWQRhhEs7LP/TByoC15A0br++xLxRz4r7HBLGAWQQDpg
26
+ 66BJ2TBVjxS6K64tKbq7+ACyrOZGgTfNHACh4M076y0x0oRf/rwBrU39/KRfuhbb
27
+ cm+nNCEtO35gTmZ2bVDHLGvWazi3gJt6+huQjfXTCUUG2YYBxwhu+GPdAGQPxpf9
28
+ lkHilIrX69jq8wMPpBhlaw2mRmeSL50Wv5u6xVBvOHhXFSP1crXM95vfLhLyRYod
29
+ W2A=
30
30
  -----END CERTIFICATE-----
31
- date: 2020-12-13 00:00:00.000000000 Z
32
- dependencies: []
31
+ date: 2021-05-02 00:00:00.000000000 Z
32
+ dependencies:
33
+ - !ruby/object:Gem::Dependency
34
+ name: refinements
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '8.0'
40
+ type: :runtime
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '8.0'
33
47
  description:
34
48
  email:
35
49
  - brooke@alchemists.io
@@ -43,12 +57,12 @@ files:
43
57
  - README.adoc
44
58
  - lib/versionaire.rb
45
59
  - lib/versionaire/cast.rb
46
- - lib/versionaire/conversion.rb
47
60
  - lib/versionaire/errors/base.rb
48
- - lib/versionaire/errors/conversion.rb
61
+ - lib/versionaire/errors/cast.rb
49
62
  - lib/versionaire/errors/invalid_number.rb
50
63
  - lib/versionaire/errors/negative_number.rb
51
- - lib/versionaire/filler.rb
64
+ - lib/versionaire/extensions/option_parser.rb
65
+ - lib/versionaire/function.rb
52
66
  - lib/versionaire/identity.rb
53
67
  - lib/versionaire/version.rb
54
68
  homepage: https://www.alchemists.io/projects/versionaire
@@ -67,14 +81,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
67
81
  requirements:
68
82
  - - "~>"
69
83
  - !ruby/object:Gem::Version
70
- version: '2.7'
84
+ version: '3.0'
71
85
  required_rubygems_version: !ruby/object:Gem::Requirement
72
86
  requirements:
73
87
  - - ">="
74
88
  - !ruby/object:Gem::Version
75
89
  version: '0'
76
90
  requirements: []
77
- rubygems_version: 3.2.0
91
+ rubygems_version: 3.2.16
78
92
  signing_key:
79
93
  specification_version: 4
80
94
  summary: Provides an immutable, thread-safe, and semantic version type.
metadata.gz.sig CHANGED
Binary file
@@ -1,9 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Versionaire
4
- module Errors
5
- # Thrown when attempting to convert (cast) an invalid primitive to a version.
6
- class Conversion < Base
7
- end
8
- end
9
- end
@@ -1,19 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Versionaire
4
- # Ensures an array can be filled to a certain size with default elements.
5
- class Filler
6
- def initialize pad = 0, max: 2
7
- @pad = pad
8
- @max = max
9
- end
10
-
11
- def call array
12
- array.dup.fill pad, array.size..max
13
- end
14
-
15
- private
16
-
17
- attr_reader :pad, :max
18
- end
19
- end