unit_measurements 4.8.0 → 4.10.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 +4 -4
- data/.github/workflows/main.yml +12 -11
- data/.github/workflows/pages.yml +31 -0
- data/CHANGELOG.md +19 -1
- 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/unit_groups/all.rb +1 -6
- data/lib/unit_measurements/unit_groups/information_entropy.rb +15 -0
- data/lib/unit_measurements/version.rb +2 -1
- data/lib/unit_measurements.rb +16 -0
- data/unit_measurements.gemspec +1 -0
- data/units.md +13 -0
- metadata +5 -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
|