unit_measurements 4.9.0 → 4.10.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/main.yml +12 -11
- data/.github/workflows/pages.yml +31 -0
- data/CHANGELOG.md +10 -0
- data/Gemfile.lock +1 -1
- data/README.md +36 -69
- data/lib/unit_measurements/arithmetic.rb +91 -20
- data/lib/unit_measurements/base.rb +56 -0
- data/lib/unit_measurements/comparison.rb +45 -4
- data/lib/unit_measurements/conversion.rb +40 -10
- data/lib/unit_measurements/errors/parse_error.rb +20 -0
- data/lib/unit_measurements/errors/primitive_unit_already_set_error.rb +11 -0
- data/lib/unit_measurements/errors/unit_already_defined_error.rb +20 -0
- data/lib/unit_measurements/errors/unit_error.rb +19 -0
- data/lib/unit_measurements/formatter.rb +31 -9
- data/lib/unit_measurements/math.rb +51 -14
- data/lib/unit_measurements/measurement.rb +251 -8
- data/lib/unit_measurements/normalizer.rb +92 -3
- data/lib/unit_measurements/parser.rb +169 -7
- data/lib/unit_measurements/unit.rb +128 -1
- data/lib/unit_measurements/unit_group.rb +160 -11
- data/lib/unit_measurements/unit_group_builder.rb +133 -0
- data/lib/unit_measurements/version.rb +2 -1
- data/lib/unit_measurements.rb +16 -0
- data/unit_measurements.gemspec +1 -0
- metadata +4 -2
@@ -3,14 +3,28 @@
|
|
3
3
|
# -*- warn_indent: true -*-
|
4
4
|
|
5
5
|
module UnitMeasurements
|
6
|
+
# The +UnitMeasurements::Conversion+ mixin module defines methods for converting
|
7
|
+
# quantity of the measurement to various numeric types. These methods allow for
|
8
|
+
# flexibility in handling measurements in different numeric formats.
|
9
|
+
#
|
10
|
+
# This module is included into the +Measurement+ class to allow conversion of
|
11
|
+
# the measurement quantity to other numeric types.
|
12
|
+
#
|
13
|
+
# @see Measurement
|
14
|
+
# @author {Harshal V. Ladhe}[https://shivam091.github.io/]
|
15
|
+
# @since 1.7.0
|
6
16
|
module Conversion
|
7
17
|
# Converts quantity of the measurement to +Integer+.
|
8
18
|
#
|
9
19
|
# @example
|
10
|
-
# UnitMeasurements::
|
11
|
-
# => 2
|
20
|
+
# UnitMeasurements::Length.new(2.25567, "km").to_i
|
21
|
+
# => 2 km
|
12
22
|
#
|
13
23
|
# @return [Measurement]
|
24
|
+
# A new +Measurement+ instance with the quantity converted to an +Integer+.
|
25
|
+
#
|
26
|
+
# @author {Harshal V. Ladhe}[https://shivam091.github.io/]
|
27
|
+
# @since 1.7.0
|
14
28
|
def to_i
|
15
29
|
self.class.new(quantity.to_i, unit)
|
16
30
|
end
|
@@ -18,10 +32,14 @@ module UnitMeasurements
|
|
18
32
|
# Converts quantity of the measurement to +Float+.
|
19
33
|
#
|
20
34
|
# @example
|
21
|
-
# UnitMeasurements::
|
22
|
-
# => 2.25567
|
35
|
+
# UnitMeasurements::Length.new(2.25567, "km").to_f
|
36
|
+
# => 2.25567 km
|
23
37
|
#
|
24
38
|
# @return [Measurement]
|
39
|
+
# A new +Measurement+ instance with the quantity converted to a +Float+.
|
40
|
+
#
|
41
|
+
# @author {Harshal V. Ladhe}[https://shivam091.github.io/]
|
42
|
+
# @since 1.7.0
|
25
43
|
def to_f
|
26
44
|
self.class.new(quantity.to_f, unit)
|
27
45
|
end
|
@@ -29,10 +47,14 @@ module UnitMeasurements
|
|
29
47
|
# Converts quantity of the measurement to +Rational+.
|
30
48
|
#
|
31
49
|
# @example
|
32
|
-
# UnitMeasurements::
|
33
|
-
# => 225567/100000
|
50
|
+
# UnitMeasurements::Length.new(2.25567, "km").to_r
|
51
|
+
# => 225567/100000 km
|
34
52
|
#
|
35
53
|
# @return [Measurement]
|
54
|
+
# A new +Measurement+ instance with the quantity converted to a +Rational+.
|
55
|
+
#
|
56
|
+
# @author {Harshal V. Ladhe}[https://shivam091.github.io/]
|
57
|
+
# @since 1.7.0
|
36
58
|
def to_r
|
37
59
|
self.class.new(quantity.to_r, unit)
|
38
60
|
end
|
@@ -40,10 +62,14 @@ module UnitMeasurements
|
|
40
62
|
# Converts quantity of the measurement to +Complex+.
|
41
63
|
#
|
42
64
|
# @example
|
43
|
-
# UnitMeasurements::
|
44
|
-
# => 2.25567+0i
|
65
|
+
# UnitMeasurements::Length.new(2.25567, "km").to_c
|
66
|
+
# => 2.25567+0i km
|
45
67
|
#
|
46
68
|
# @return [Measurement]
|
69
|
+
# A new +Measurement+ instance with the quantity converted to a +Complex+ number.
|
70
|
+
#
|
71
|
+
# @author {Harshal V. Ladhe}[https://shivam091.github.io/]
|
72
|
+
# @since 1.7.0
|
47
73
|
def to_c
|
48
74
|
self.class.new(quantity.to_c, unit)
|
49
75
|
end
|
@@ -51,10 +77,14 @@ module UnitMeasurements
|
|
51
77
|
# Converts quantity of the measurement to +BigDecimal+.
|
52
78
|
#
|
53
79
|
# @example
|
54
|
-
# UnitMeasurements::
|
55
|
-
# => 2.25567
|
80
|
+
# UnitMeasurements::Length.new(2.25567, "km").to_d
|
81
|
+
# => 2.25567 km
|
56
82
|
#
|
57
83
|
# @return [Measurement]
|
84
|
+
# A new +Measurement+ instance with the quantity converted to a +BigDecimal+.
|
85
|
+
#
|
86
|
+
# @author {Harshal V. Ladhe}[https://shivam091.github.io/]
|
87
|
+
# @since 1.7.0
|
58
88
|
def to_d
|
59
89
|
self.class.new(quantity.to_d, unit)
|
60
90
|
end
|
@@ -3,9 +3,29 @@
|
|
3
3
|
# -*- warn_indent: true -*-
|
4
4
|
|
5
5
|
module UnitMeasurements
|
6
|
+
# The +UnitMeasurements::ParseError+ class is used to represent an error
|
7
|
+
# condition where the library encounters difficulty in parsing a given string.
|
8
|
+
# This can occur due to invalid or unexpected input formats.
|
9
|
+
#
|
10
|
+
# The error message states that the parser encountered an error while parsing
|
11
|
+
# and provides the string that caused the parsing error.
|
12
|
+
#
|
13
|
+
# @see BaseError
|
14
|
+
# @author {Harshal V. Ladhe}[https://shivam091.github.io/]
|
15
|
+
# @since 1.0.0
|
6
16
|
class ParseError < BaseError
|
17
|
+
# The input string that caused the error while parsing.
|
18
|
+
#
|
19
|
+
# @author {Harshal V. Ladhe}[https://shivam091.github.io/]
|
20
|
+
# @since 1.0.0
|
7
21
|
attr_reader :string
|
8
22
|
|
23
|
+
# Initializes a new +ParseError+ instance.
|
24
|
+
#
|
25
|
+
# @param [String] string The input string that caused the error while parsing.
|
26
|
+
#
|
27
|
+
# @author {Harshal V. Ladhe}[https://shivam091.github.io/]
|
28
|
+
# @since 1.0.0
|
9
29
|
def initialize(string)
|
10
30
|
@string = string
|
11
31
|
|
@@ -3,7 +3,18 @@
|
|
3
3
|
# -*- warn_indent: true -*-
|
4
4
|
|
5
5
|
module UnitMeasurements
|
6
|
+
# The +UnitMeasurements::PrimitiveUnitAlreadySetError+ class represents an
|
7
|
+
# error that occurs when attempting to set a primitive unit for the unit group
|
8
|
+
# that already has a primitive unit defined.
|
9
|
+
#
|
10
|
+
# @see BaseError
|
11
|
+
# @author {Harshal V. Ladhe}[https://shivam091.github.io/]
|
12
|
+
# @since 4.0.0
|
6
13
|
class PrimitiveUnitAlreadySetError < BaseError
|
14
|
+
# Initializes a new +PrimitiveUnitAlreadySetError+ instance.
|
15
|
+
#
|
16
|
+
# @author {Harshal V. Ladhe}[https://shivam091.github.io/]
|
17
|
+
# @since 4.0.0
|
7
18
|
def initialize
|
8
19
|
super("The primitive unit is already set for the unit group.")
|
9
20
|
end
|
@@ -3,9 +3,29 @@
|
|
3
3
|
# -*- warn_indent: true -*-
|
4
4
|
|
5
5
|
module UnitMeasurements
|
6
|
+
# The +UnitMeasurements::UnitAlreadyDefinedError+ class is used to indicate
|
7
|
+
# that an attempt was made to define a unit that has already been defined
|
8
|
+
# within a unit group.
|
9
|
+
#
|
10
|
+
# The error message states that the unit is already defined and provides the
|
11
|
+
# name of the conflicting unit.
|
12
|
+
#
|
13
|
+
# @see BaseError
|
14
|
+
# @author {Harshal V. Ladhe}[https://shivam091.github.io/]
|
15
|
+
# @since 1.0.0
|
6
16
|
class UnitAlreadyDefinedError < BaseError
|
17
|
+
# The name of the unit that is already defined.
|
18
|
+
#
|
19
|
+
# @author {Harshal V. Ladhe}[https://shivam091.github.io/]
|
20
|
+
# @since 1.0.0
|
7
21
|
attr_reader :unit
|
8
22
|
|
23
|
+
# Initializes a new +UnitAlreadyDefinedError+ instance.
|
24
|
+
#
|
25
|
+
# @param [String] unit The name of the unit that is already defined.
|
26
|
+
#
|
27
|
+
# @author {Harshal V. Ladhe}[https://shivam091.github.io/]
|
28
|
+
# @since 1.0.0
|
9
29
|
def initialize(unit)
|
10
30
|
@unit = unit
|
11
31
|
|
@@ -3,9 +3,28 @@
|
|
3
3
|
# -*- warn_indent: true -*-
|
4
4
|
|
5
5
|
module UnitMeasurements
|
6
|
+
# The +UnitMeasurements::UnitError+ class is used to indicate that an invalid
|
7
|
+
# unit was encountered. The error message states that the unit is invalid and
|
8
|
+
# provides the name of the problematic unit.
|
9
|
+
#
|
10
|
+
# This error is raised when the unit is not defined within the unit group.
|
11
|
+
#
|
12
|
+
# @see BaseError
|
13
|
+
# @author {Harshal V. Ladhe}[https://shivam091.github.io/]
|
14
|
+
# @since 1.0.0
|
6
15
|
class UnitError < BaseError
|
16
|
+
# The name of the invalid unit.
|
17
|
+
#
|
18
|
+
# @author {Harshal V. Ladhe}[https://shivam091.github.io/]
|
19
|
+
# @since 1.0.0
|
7
20
|
attr_reader :unit
|
8
21
|
|
22
|
+
# Initializes a new +UnitError+ instance.
|
23
|
+
#
|
24
|
+
# @param [String] unit The name of the invalid unit.
|
25
|
+
#
|
26
|
+
# @author {Harshal V. Ladhe}[https://shivam091.github.io/]
|
27
|
+
# @since 1.0.0
|
9
28
|
def initialize(unit)
|
10
29
|
@unit = unit
|
11
30
|
|
@@ -3,23 +3,45 @@
|
|
3
3
|
# -*- warn_indent: true -*-
|
4
4
|
|
5
5
|
module UnitMeasurements
|
6
|
+
# The +UnitMeasurements::Formatter+ mixin module contains methods for formatting
|
7
|
+
# measurements into human-readable strings. It provides the ability to customize
|
8
|
+
# the output format based on user-defined preferences.
|
9
|
+
#
|
10
|
+
# This module is included in the +Measurement+ class to allow customization of
|
11
|
+
# the output of the measurements.
|
12
|
+
#
|
13
|
+
# @see Measurement
|
14
|
+
# @author {Harshal V. Ladhe}[https://shivam091.github.io/]
|
15
|
+
# @since 1.1.0
|
6
16
|
module Formatter
|
7
|
-
# The default format for formatting measurements.
|
17
|
+
# The default format used for formatting measurements. It is a format string
|
18
|
+
# containing placeholders for +quantity+ and +unit+.
|
8
19
|
DEFAULT_FORMAT = "%.2<quantity>f %<unit>s".freeze
|
9
20
|
|
10
21
|
# Formats measurement to certain formatted string specified by +format+.
|
11
|
-
# If +format+ is not specified, it uses +DEFAULT_FORMAT+ for
|
12
|
-
#
|
22
|
+
# If +format+ is not specified, it uses +DEFAULT_FORMAT+ for formatting the
|
23
|
+
# measurement.
|
24
|
+
#
|
25
|
+
# The format method allows for customization of the output format of a
|
26
|
+
# measurement. It uses format placeholders for +quantity+ and +unit+. If no
|
27
|
+
# custom format is provided, it will use the +DEFAULT_FORMAT+.
|
13
28
|
#
|
14
29
|
# @example
|
15
|
-
# UnitMeasurements::
|
16
|
-
# => "
|
17
|
-
#
|
18
|
-
#
|
30
|
+
# UnitMeasurements::Length.new(1, "m").to("in").format
|
31
|
+
# => "39.37 in"
|
32
|
+
#
|
33
|
+
# UnitMeasurements::Length.new(1, "m").to("in").format("%.4<quantity>f %<unit>s")
|
34
|
+
# => "39.3701 in"
|
35
|
+
#
|
36
|
+
# @param [String, optional] format
|
37
|
+
# The custom format string for formatting the measurement. If not provided,
|
38
|
+
# +DEFAULT_FORMAT+ is used.
|
19
39
|
#
|
20
|
-
# @
|
40
|
+
# @return [String] A formatted string representing the measurement.
|
21
41
|
#
|
22
|
-
# @
|
42
|
+
# @see DEFAULT_FORMAT
|
43
|
+
# @author {Harshal V. Ladhe}[https://shivam091.github.io/]
|
44
|
+
# @since 1.1.0
|
23
45
|
def format(format = nil)
|
24
46
|
kwargs = {quantity: quantity, unit: unit.to_s}
|
25
47
|
|
@@ -3,17 +3,32 @@
|
|
3
3
|
# -*- warn_indent: true -*-
|
4
4
|
|
5
5
|
module UnitMeasurements
|
6
|
+
# The +UnitMeasurements::Math+ mixin module provides methods for performing
|
7
|
+
# mathematical functions on the measurement.
|
8
|
+
#
|
9
|
+
# This module is included in the +Measurement+ class to allow mathematical
|
10
|
+
# functions on the measurement.
|
11
|
+
#
|
12
|
+
# @see Measurement
|
13
|
+
# @author {Harshal V. Ladhe}[https://shivam091.github.io/]
|
14
|
+
# @since 1.6.0
|
6
15
|
module Math
|
7
|
-
# Rounds quantity of the measurement. If
|
8
|
-
#
|
16
|
+
# Rounds quantity of the measurement. If +ndigits+ is not specified, quantity
|
17
|
+
# is rounded to +Integer+.
|
9
18
|
#
|
10
19
|
# @example
|
11
|
-
# UnitMeasurements::
|
12
|
-
# =>
|
20
|
+
# UnitMeasurements::Length.new(17.625, "m").round
|
21
|
+
# => 18 m
|
13
22
|
#
|
14
|
-
#
|
23
|
+
# UnitMeasurements::Length.new(17.625, "m").round(2)
|
24
|
+
# => 17.63 m
|
15
25
|
#
|
16
|
-
# @
|
26
|
+
# @param [Integer, optional] ndigits The number of digits to round to.
|
27
|
+
#
|
28
|
+
# @return [Measurement] A new +Measurement+ instance with the rounded quantity.
|
29
|
+
#
|
30
|
+
# @author {Harshal V. Ladhe}[https://shivam091.github.io/]
|
31
|
+
# @since 1.6.0
|
17
32
|
def round(ndigits = 0)
|
18
33
|
self.class.new(quantity.round(ndigits), unit)
|
19
34
|
end
|
@@ -25,30 +40,52 @@ module UnitMeasurements
|
|
25
40
|
# => 17.625 m
|
26
41
|
#
|
27
42
|
# @return [Measurement]
|
43
|
+
# A new +Measurement+ instance with the absolute value of the quantity.
|
44
|
+
#
|
45
|
+
# @author {Harshal V. Ladhe}[https://shivam091.github.io/]
|
46
|
+
# @since 1.6.0
|
28
47
|
def abs
|
29
48
|
self.class.new(quantity.abs, unit)
|
30
49
|
end
|
31
50
|
|
32
|
-
#
|
51
|
+
# Returns floored quantity of the measurement. If +ndigits+ is not specified,
|
52
|
+
# quantity is rounded to next lower +Integer+.
|
33
53
|
#
|
34
54
|
# @example
|
35
55
|
# UnitMeasurements::Length.new(17.625, "m").floor
|
36
56
|
# => 17 m
|
37
57
|
#
|
38
|
-
#
|
39
|
-
|
40
|
-
|
58
|
+
# UnitMeasurements::Length.new(17.625, "m").floor(2)
|
59
|
+
# => 17.62 m
|
60
|
+
#
|
61
|
+
# @param [Integer, optional] ndigits The number of digits to round to.
|
62
|
+
#
|
63
|
+
# @return [Measurement] A new +Measurement+ instance with the floored quantity.
|
64
|
+
#
|
65
|
+
# @author {Harshal V. Ladhe}[https://shivam091.github.io/]
|
66
|
+
# @since 1.6.0
|
67
|
+
def floor(ndigits =0)
|
68
|
+
self.class.new(quantity.floor(ndigits), unit)
|
41
69
|
end
|
42
70
|
|
43
|
-
#
|
71
|
+
# Returns ceiled quantity of the measurement. If +ndigits+ is not specified,
|
72
|
+
# quantity is rounded to next higher +Integer+.
|
44
73
|
#
|
45
74
|
# @example
|
46
75
|
# UnitMeasurements::Length.new(17.625, "m").ceil
|
47
76
|
# => 18 m
|
48
77
|
#
|
49
|
-
#
|
50
|
-
|
51
|
-
|
78
|
+
# UnitMeasurements::Length.new(17.625, "m").ceil(2)
|
79
|
+
# => 17.63 m
|
80
|
+
#
|
81
|
+
# @param [Integer, optional] ndigits The number of digits to round to.
|
82
|
+
#
|
83
|
+
# @return [Measurement] A new +Measurement+ instance with the ceiled quantity.
|
84
|
+
#
|
85
|
+
# @author {Harshal V. Ladhe}[https://shivam091.github.io/]
|
86
|
+
# @since 1.6.0
|
87
|
+
def ceil(ndigits =0)
|
88
|
+
self.class.new(quantity.ceil(ndigits), unit)
|
52
89
|
end
|
53
90
|
end
|
54
91
|
end
|