unit_measurements_us_complete 5.17.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 +7 -0
- data/.github/workflows/main.yml +31 -0
- data/.github/workflows/pages.yml +31 -0
- data/.gitignore +12 -0
- data/.rspec +3 -0
- data/.yardopts +2 -0
- data/CHANGELOG.md +645 -0
- data/Gemfile +7 -0
- data/Gemfile.lock +56 -0
- data/LICENSE.md +21 -0
- data/README.md +511 -0
- data/Rakefile +10 -0
- data/lib/unit_measurements/arithmetic.rb +225 -0
- data/lib/unit_measurements/base.rb +177 -0
- data/lib/unit_measurements/cache.rb +173 -0
- data/lib/unit_measurements/comparison.rb +64 -0
- data/lib/unit_measurements/configuration.rb +64 -0
- data/lib/unit_measurements/conversion.rb +92 -0
- data/lib/unit_measurements/errors/blank_quantity_error.rb +21 -0
- data/lib/unit_measurements/errors/blank_unit_error.rb +21 -0
- data/lib/unit_measurements/errors/missing_primitive_unit_error.rb +24 -0
- data/lib/unit_measurements/errors/parse_error.rb +37 -0
- data/lib/unit_measurements/errors/primitive_unit_already_set_error.rb +22 -0
- data/lib/unit_measurements/errors/unit_already_defined_error.rb +37 -0
- data/lib/unit_measurements/errors/unit_error.rb +36 -0
- data/lib/unit_measurements/extras/conversion_methods.rb +87 -0
- data/lib/unit_measurements/extras/numeric_methods.rb +85 -0
- data/lib/unit_measurements/formatter.rb +58 -0
- data/lib/unit_measurements/math.rb +120 -0
- data/lib/unit_measurements/measurement.rb +539 -0
- data/lib/unit_measurements/normalizer.rb +155 -0
- data/lib/unit_measurements/parser.rb +220 -0
- data/lib/unit_measurements/unit.rb +243 -0
- data/lib/unit_measurements/unit_group.rb +297 -0
- data/lib/unit_measurements/unit_group_builder.rb +224 -0
- data/lib/unit_measurements/unit_groups/acceleration.rb +36 -0
- data/lib/unit_measurements/unit_groups/all.rb +56 -0
- data/lib/unit_measurements/unit_groups/amount_of_substance.rb +13 -0
- data/lib/unit_measurements/unit_groups/angular_acceleration.rb +14 -0
- data/lib/unit_measurements/unit_groups/angular_velocity.rb +25 -0
- data/lib/unit_measurements/unit_groups/area.rb +49 -0
- data/lib/unit_measurements/unit_groups/catalytic_activity.rb +13 -0
- data/lib/unit_measurements/unit_groups/density.rb +33 -0
- data/lib/unit_measurements/unit_groups/dynamic_viscosity.rb +22 -0
- data/lib/unit_measurements/unit_groups/electric_charge.rb +20 -0
- data/lib/unit_measurements/unit_groups/electric_conductance.rb +15 -0
- data/lib/unit_measurements/unit_groups/electric_current.rb +19 -0
- data/lib/unit_measurements/unit_groups/electric_dipole_moment.rb +13 -0
- data/lib/unit_measurements/unit_groups/electric_potential.rb +17 -0
- data/lib/unit_measurements/unit_groups/electric_quadrupole_moment.rb +14 -0
- data/lib/unit_measurements/unit_groups/electrical_capacitance.rb +15 -0
- data/lib/unit_measurements/unit_groups/electrical_elastance.rb +13 -0
- data/lib/unit_measurements/unit_groups/electrical_inductance.rb +15 -0
- data/lib/unit_measurements/unit_groups/electrical_resistance.rb +16 -0
- data/lib/unit_measurements/unit_groups/energy.rb +58 -0
- data/lib/unit_measurements/unit_groups/force.rb +47 -0
- data/lib/unit_measurements/unit_groups/frequency.rb +16 -0
- data/lib/unit_measurements/unit_groups/illuminance.rb +18 -0
- data/lib/unit_measurements/unit_groups/information_entropy.rb +15 -0
- data/lib/unit_measurements/unit_groups/kinetic_viscosity.rb +18 -0
- data/lib/unit_measurements/unit_groups/length.rb +67 -0
- data/lib/unit_measurements/unit_groups/luminance.rb +21 -0
- data/lib/unit_measurements/unit_groups/luminous_flux.rb +11 -0
- data/lib/unit_measurements/unit_groups/luminous_intensity.rb +13 -0
- data/lib/unit_measurements/unit_groups/magnetic_field.rb +13 -0
- data/lib/unit_measurements/unit_groups/magnetic_flux.rb +15 -0
- data/lib/unit_measurements/unit_groups/magnetic_induction.rb +13 -0
- data/lib/unit_measurements/unit_groups/magnetomotive_force.rb +13 -0
- data/lib/unit_measurements/unit_groups/mass_flow_rate.rb +49 -0
- data/lib/unit_measurements/unit_groups/plane_angle.rb +30 -0
- data/lib/unit_measurements/unit_groups/power.rb +54 -0
- data/lib/unit_measurements/unit_groups/pressure.rb +60 -0
- data/lib/unit_measurements/unit_groups/quantity.rb +14 -0
- data/lib/unit_measurements/unit_groups/radiation_absorbed_dose.rb +14 -0
- data/lib/unit_measurements/unit_groups/radiation_equivalent_dose.rb +13 -0
- data/lib/unit_measurements/unit_groups/radiation_exposure.rb +15 -0
- data/lib/unit_measurements/unit_groups/radioactivity.rb +14 -0
- data/lib/unit_measurements/unit_groups/solid_angle.rb +18 -0
- data/lib/unit_measurements/unit_groups/sound_level.rb +13 -0
- data/lib/unit_measurements/unit_groups/temperature.rb +19 -0
- data/lib/unit_measurements/unit_groups/time.rb +29 -0
- data/lib/unit_measurements/unit_groups/torque.rb +40 -0
- data/lib/unit_measurements/unit_groups/velocity.rb +37 -0
- data/lib/unit_measurements/unit_groups/volume.rb +67 -0
- data/lib/unit_measurements/unit_groups/volumetric_flow_rate.rb +35 -0
- data/lib/unit_measurements/unit_groups/weight.rb +55 -0
- data/lib/unit_measurements/version.rb +8 -0
- data/lib/unit_measurements.rb +7 -0
- data/unit_measurements.gemspec +43 -0
- data/units.md +843 -0
- metadata +216 -0
@@ -0,0 +1,92 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
# -*- frozen_string_literal: true -*-
|
3
|
+
# -*- warn_indent: true -*-
|
4
|
+
|
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
|
16
|
+
module Conversion
|
17
|
+
# Converts quantity of the measurement to +Integer+.
|
18
|
+
#
|
19
|
+
# @example
|
20
|
+
# UnitMeasurements::Length.new(2.25567, "km").to_i
|
21
|
+
# => 2 km
|
22
|
+
#
|
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
|
28
|
+
def to_i
|
29
|
+
self.class.new(quantity.to_i, unit)
|
30
|
+
end
|
31
|
+
|
32
|
+
# Converts quantity of the measurement to +Float+.
|
33
|
+
#
|
34
|
+
# @example
|
35
|
+
# UnitMeasurements::Length.new(2.25567, "km").to_f
|
36
|
+
# => 2.25567 km
|
37
|
+
#
|
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
|
43
|
+
def to_f
|
44
|
+
self.class.new(quantity.to_f, unit)
|
45
|
+
end
|
46
|
+
|
47
|
+
# Converts quantity of the measurement to +Rational+.
|
48
|
+
#
|
49
|
+
# @example
|
50
|
+
# UnitMeasurements::Length.new(2.25567, "km").to_r
|
51
|
+
# => 225567/100000 km
|
52
|
+
#
|
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
|
58
|
+
def to_r
|
59
|
+
self.class.new(quantity.to_r, unit)
|
60
|
+
end
|
61
|
+
|
62
|
+
# Converts quantity of the measurement to +Complex+.
|
63
|
+
#
|
64
|
+
# @example
|
65
|
+
# UnitMeasurements::Length.new(2.25567, "km").to_c
|
66
|
+
# => 2.25567+0i km
|
67
|
+
#
|
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
|
73
|
+
def to_c
|
74
|
+
self.class.new(quantity.to_c, unit)
|
75
|
+
end
|
76
|
+
|
77
|
+
# Converts quantity of the measurement to +BigDecimal+.
|
78
|
+
#
|
79
|
+
# @example
|
80
|
+
# UnitMeasurements::Length.new(2.25567, "km").to_d
|
81
|
+
# => 2.25567 km
|
82
|
+
#
|
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
|
88
|
+
def to_d
|
89
|
+
self.class.new(quantity.to_d, unit)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
# -*- frozen_string_literal: true -*-
|
3
|
+
# -*- warn_indent: true -*-
|
4
|
+
|
5
|
+
module UnitMeasurements
|
6
|
+
# The +UnitMeasurements::BlankQuantityError+ class represents an error that
|
7
|
+
# occurs when trying to initialize the +Measurement+ with a blank quantity.
|
8
|
+
#
|
9
|
+
# @see BaseError
|
10
|
+
# @author {Harshal V. Ladhe}[https://shivam091.github.io/]
|
11
|
+
# @since 5.10.0
|
12
|
+
class BlankQuantityError < BaseError
|
13
|
+
# Initializes a new +BlankQuantityError+ instance.
|
14
|
+
#
|
15
|
+
# @author {Harshal V. Ladhe}[https://shivam091.github.io/]
|
16
|
+
# @since 5.10.0
|
17
|
+
def initialize
|
18
|
+
super("Quantity cannot be blank.")
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
# -*- frozen_string_literal: true -*-
|
3
|
+
# -*- warn_indent: true -*-
|
4
|
+
|
5
|
+
module UnitMeasurements
|
6
|
+
# The +UnitMeasurements::BlankUnitError+ class represents an error that
|
7
|
+
# occurs when trying to initialize the +Measurement+ with a blank unit.
|
8
|
+
#
|
9
|
+
# @see BaseError
|
10
|
+
# @author {Harshal V. Ladhe}[https://shivam091.github.io/]
|
11
|
+
# @since 5.10.0
|
12
|
+
class BlankUnitError < BaseError
|
13
|
+
# Initializes a new +BlankUnitError+ instance.
|
14
|
+
#
|
15
|
+
# @author {Harshal V. Ladhe}[https://shivam091.github.io/]
|
16
|
+
# @since 5.10.0
|
17
|
+
def initialize
|
18
|
+
super("Unit cannot be blank.")
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
# -*- frozen_string_literal: true -*-
|
3
|
+
# -*- warn_indent: true -*-
|
4
|
+
|
5
|
+
module UnitMeasurements
|
6
|
+
# The +UnitMeasurements::MissingPrimitiveUnitError+ class represents an error
|
7
|
+
# that occurs when the primitive unit is not set for a unit group.
|
8
|
+
#
|
9
|
+
# This error is raised when a user attempts to convert a measurement to the
|
10
|
+
# primitive unit of a unit group that does not have a primitive unit defined.
|
11
|
+
#
|
12
|
+
# @see BaseError
|
13
|
+
# @author {Harshal V. Ladhe}[https://shivam091.github.io/]
|
14
|
+
# @since 5.12.0
|
15
|
+
class MissingPrimitiveUnitError < BaseError
|
16
|
+
# Initializes a new +MissingPrimitiveUnitError+ instance.
|
17
|
+
#
|
18
|
+
# @author {Harshal V. Ladhe}[https://shivam091.github.io/]
|
19
|
+
# @since 5.12.0
|
20
|
+
def initialize
|
21
|
+
super("The primitive unit is not set for the unit group.")
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
# -*- frozen_string_literal: true -*-
|
3
|
+
# -*- warn_indent: true -*-
|
4
|
+
|
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
|
16
|
+
class ParseError < BaseError
|
17
|
+
# The input string that caused the error while parsing.
|
18
|
+
#
|
19
|
+
# @return [String] The input string that caused the error while parsing.
|
20
|
+
#
|
21
|
+
# @author {Harshal V. Ladhe}[https://shivam091.github.io/]
|
22
|
+
# @since 1.0.0
|
23
|
+
attr_reader :string
|
24
|
+
|
25
|
+
# Initializes a new +ParseError+ instance.
|
26
|
+
#
|
27
|
+
# @param [String] string The input string that caused the error while parsing.
|
28
|
+
#
|
29
|
+
# @author {Harshal V. Ladhe}[https://shivam091.github.io/]
|
30
|
+
# @since 1.0.0
|
31
|
+
def initialize(string)
|
32
|
+
@string = string
|
33
|
+
|
34
|
+
super("Unable to parse: '#{string}'.")
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
# -*- frozen_string_literal: true -*-
|
3
|
+
# -*- warn_indent: true -*-
|
4
|
+
|
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
|
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
|
18
|
+
def initialize
|
19
|
+
super("The primitive unit is already set for the unit group.")
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
# -*- frozen_string_literal: true -*-
|
3
|
+
# -*- warn_indent: true -*-
|
4
|
+
|
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
|
16
|
+
class UnitAlreadyDefinedError < BaseError
|
17
|
+
# The name of the unit that is already defined.
|
18
|
+
#
|
19
|
+
# @return [String] The name of the unit that is already defined.
|
20
|
+
#
|
21
|
+
# @author {Harshal V. Ladhe}[https://shivam091.github.io/]
|
22
|
+
# @since 1.0.0
|
23
|
+
attr_reader :unit
|
24
|
+
|
25
|
+
# Initializes a new +UnitAlreadyDefinedError+ instance.
|
26
|
+
#
|
27
|
+
# @param [String] unit The name of the unit that is already defined.
|
28
|
+
#
|
29
|
+
# @author {Harshal V. Ladhe}[https://shivam091.github.io/]
|
30
|
+
# @since 1.0.0
|
31
|
+
def initialize(unit)
|
32
|
+
@unit = unit
|
33
|
+
|
34
|
+
super("Unit already defined: '#{unit}'.")
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
# -*- frozen_string_literal: true -*-
|
3
|
+
# -*- warn_indent: true -*-
|
4
|
+
|
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
|
15
|
+
class UnitError < BaseError
|
16
|
+
# The name of the invalid unit.
|
17
|
+
#
|
18
|
+
# @return [String] The name of the invalid unit.
|
19
|
+
#
|
20
|
+
# @author {Harshal V. Ladhe}[https://shivam091.github.io/]
|
21
|
+
# @since 1.0.0
|
22
|
+
attr_reader :unit
|
23
|
+
|
24
|
+
# Initializes a new +UnitError+ instance.
|
25
|
+
#
|
26
|
+
# @param [String] unit The name of the invalid unit.
|
27
|
+
#
|
28
|
+
# @author {Harshal V. Ladhe}[https://shivam091.github.io/]
|
29
|
+
# @since 1.0.0
|
30
|
+
def initialize(unit)
|
31
|
+
@unit = unit
|
32
|
+
|
33
|
+
super("Invalid unit: '#{unit}'.")
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
# -*- frozen_string_literal: true -*-
|
3
|
+
# -*- warn_indent: true -*-
|
4
|
+
|
5
|
+
module UnitMeasurements
|
6
|
+
# This module provides functionality to define conversion methods for a list
|
7
|
+
# of units within a unit group. If units are empty, it defaults to defining
|
8
|
+
# methods for all units in the unit group. These methods allow easy conversion
|
9
|
+
# between different units within a given unit group.
|
10
|
+
#
|
11
|
+
# This module is included in the +Measurement+ class to allow defining conversion
|
12
|
+
# methods for specified units.
|
13
|
+
#
|
14
|
+
# @see Measurement
|
15
|
+
#
|
16
|
+
# @author {Harshal V. Ladhe}[https://shivam091.github.io/]
|
17
|
+
# @since 5.15.0
|
18
|
+
module ConversionMethods
|
19
|
+
# @scope class
|
20
|
+
# Defines conversion methods for specified +units+ within the unit group.
|
21
|
+
# If +units+ are empty, it defaults to defining methods for all units within
|
22
|
+
# the unit group.
|
23
|
+
#
|
24
|
+
# @example Define conversion methods for metres, centimetres, and millimetres:
|
25
|
+
# UnitMeasurements::Length.define_conversion_methods("metres", :cm, :mm)
|
26
|
+
#
|
27
|
+
# @example Define conversion methods for all units within the unit group:
|
28
|
+
# UnitMeasurements::Length.define_conversion_methods
|
29
|
+
#
|
30
|
+
# @param [Array<String|Symbol>, optional] units
|
31
|
+
# An array of units' names for which conversion methods need to be defined.
|
32
|
+
# If empty, methods will be defined for all units within the unit group.
|
33
|
+
#
|
34
|
+
# @return [Array<Unit>]
|
35
|
+
# An array of units for which the conversion methods were defined.
|
36
|
+
#
|
37
|
+
# @note
|
38
|
+
# This method defines a conversion methods specifically for units that contain
|
39
|
+
# alphabetic characters in their names.
|
40
|
+
#
|
41
|
+
# @see .define_conversion_method_for
|
42
|
+
# @author {Harshal V. Ladhe}[https://shivam091.github.io/]
|
43
|
+
# @since 5.15.0
|
44
|
+
def define_conversion_methods(*units)
|
45
|
+
unit_group = self
|
46
|
+
units = units.empty? ? unit_group.units : units
|
47
|
+
|
48
|
+
units.inject([]) do |units, unit|
|
49
|
+
units << define_conversion_method_for(unit, unit_group)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
# @private
|
56
|
+
# @scope class
|
57
|
+
# Defines conversion methods for a specific +unit+ within a +unit_group+.
|
58
|
+
# These methods are defined dynamically using +define_method+.
|
59
|
+
#
|
60
|
+
# @param [String|Symbol|Unit] unit
|
61
|
+
# The unit (or its name) for which the conversion methods need to be defined.
|
62
|
+
# @param [UnitGroup] unit_group The unit group to which the unit belongs.
|
63
|
+
#
|
64
|
+
# @return [Unit]
|
65
|
+
# The unit instance for which the conversion methods were defined.
|
66
|
+
#
|
67
|
+
# @see .define_conversion_methods
|
68
|
+
# @author {Harshal V. Ladhe}[https://shivam091.github.io/]
|
69
|
+
# @since 5.15.0
|
70
|
+
def define_conversion_method_for(unit, unit_group)
|
71
|
+
unit = unit.is_a?(Unit) ? unit : unit_group.unit_for!(unit)
|
72
|
+
|
73
|
+
unit.names.each do |method_name|
|
74
|
+
# Check if the name contains alphabetic characters
|
75
|
+
next unless method_name =~ /^[a-zA-Z]+$/
|
76
|
+
|
77
|
+
define_method("in_#{method_name}") do |use_cache: false|
|
78
|
+
convert_to(unit, use_cache: use_cache)
|
79
|
+
end
|
80
|
+
alias_method "to_#{method_name}", "in_#{method_name}"
|
81
|
+
alias_method "as_#{method_name}", "in_#{method_name}"
|
82
|
+
end
|
83
|
+
|
84
|
+
unit
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
# -*- frozen_string_literal: true -*-
|
3
|
+
# -*- warn_indent: true -*-
|
4
|
+
|
5
|
+
module UnitMeasurements
|
6
|
+
# This module provides methods to define +Numeric+ methods for a list of units
|
7
|
+
# within a unit group. If units are empty, it defaults to defining methods for
|
8
|
+
# all units in the unit group.
|
9
|
+
#
|
10
|
+
# This module is included in the +Measurement+ class to allow defining numeric
|
11
|
+
# methods for specified units.
|
12
|
+
#
|
13
|
+
# @see Measurement
|
14
|
+
#
|
15
|
+
# @author {Harshal V. Ladhe}[https://shivam091.github.io/]
|
16
|
+
# @since 5.14.0
|
17
|
+
module NumericMethods
|
18
|
+
# @scope class
|
19
|
+
# Defines +Numeric+ methods for specified +units+ within the unit group. If
|
20
|
+
# +units+ are empty, it defaults to defining methods for all units within
|
21
|
+
# the unit group.
|
22
|
+
#
|
23
|
+
# @example Define numeric methods for metres, centimetres, and millimetres:
|
24
|
+
# UnitMeasurements::Length.define_numeric_methods("metres", :cm, :mm)
|
25
|
+
#
|
26
|
+
# @example Define numeric methods for all units within the unit group:
|
27
|
+
# UnitMeasurements::Length.define_numeric_methods
|
28
|
+
#
|
29
|
+
# @param [Array<String|Symbol>, optional] units
|
30
|
+
# An array of units' names for which numeric methods need to be defined.
|
31
|
+
# If empty, methods will be defined for all units within the unit group.
|
32
|
+
#
|
33
|
+
# @return [Array<Unit>] An array of units for which numeric methods were defined.
|
34
|
+
#
|
35
|
+
# @note
|
36
|
+
# This method defines a numeric methods specifically for units that contain
|
37
|
+
# alphabetic characters in their names.
|
38
|
+
#
|
39
|
+
# @see .define_numeric_method_for
|
40
|
+
#
|
41
|
+
# @author {Harshal V. Ladhe}[https://shivam091.github.io/]
|
42
|
+
# @since 5.14.0
|
43
|
+
def define_numeric_methods(*units)
|
44
|
+
unit_group = self
|
45
|
+
units = units.empty? ? unit_group.units : units
|
46
|
+
|
47
|
+
units.inject([]) do |units, unit|
|
48
|
+
units << define_numeric_method_for(unit, unit_group)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
# @private
|
55
|
+
# @scope class
|
56
|
+
# Defines a numeric method for a specific +unit+ within a +unit_group+. The
|
57
|
+
# method is defined dynamically using +define_method+ and associates the unit
|
58
|
+
# with the numeric value.
|
59
|
+
#
|
60
|
+
# @param [String|Symbol|Unit] unit
|
61
|
+
# The unit (or its name) for which the numeric method needs to be defined.
|
62
|
+
# @param [UnitGroup] unit_group The unit group to which the unit belongs.
|
63
|
+
#
|
64
|
+
# @return [Unit] The unit instance for which the method was defined.
|
65
|
+
#
|
66
|
+
# @see .define_numeric_methods
|
67
|
+
#
|
68
|
+
# @author {Harshal V. Ladhe}[https://shivam091.github.io/]
|
69
|
+
# @since 5.14.0
|
70
|
+
def define_numeric_method_for(unit, unit_group)
|
71
|
+
unit = unit.is_a?(Unit) ? unit : unit_group.unit_for!(unit)
|
72
|
+
|
73
|
+
unit.names.each do |method_name|
|
74
|
+
# Check if the name contains alphabetic characters
|
75
|
+
next unless method_name =~ /^[a-zA-Z]+$/
|
76
|
+
|
77
|
+
Numeric.define_method(method_name) do
|
78
|
+
unit_group.new(self, unit)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
unit
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
# -*- frozen_string_literal: true -*-
|
3
|
+
# -*- warn_indent: true -*-
|
4
|
+
|
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
|
16
|
+
module Formatter
|
17
|
+
# The default format used for formatting measurements. It is a format string
|
18
|
+
# containing placeholders for +quantity+ and +unit+.
|
19
|
+
DEFAULT_FORMAT = "%.2<quantity>f %<unit>s".freeze
|
20
|
+
|
21
|
+
# @deprecated This method has been deprecated in favour of {#to_fs}.
|
22
|
+
#
|
23
|
+
# This method is no longer recommended for use. Please use {#to_fs}
|
24
|
+
# instead.
|
25
|
+
def format(format = nil)
|
26
|
+
warn "DEPRECATION WARNING: The `format` method is deprecated and will be removed in upcoming release. Please use `to_fs` instead."
|
27
|
+
to_fs(format)
|
28
|
+
end
|
29
|
+
|
30
|
+
# Formats measurement to certain formatted string specified by +format+.
|
31
|
+
# If +format+ is not specified, it uses {DEFAULT_FORMAT} for formatting the
|
32
|
+
# measurement.
|
33
|
+
#
|
34
|
+
# The {#to_fs} method allows for customization of the output format of a
|
35
|
+
# measurement. It uses format placeholders for +quantity+ and +unit+.
|
36
|
+
#
|
37
|
+
# @example
|
38
|
+
# UnitMeasurements::Length.new(1, "m").to("in").to_fs
|
39
|
+
# => "39.37 in"
|
40
|
+
#
|
41
|
+
# UnitMeasurements::Length.new(1, "m").to("in").to_fs("%.4<quantity>f %<unit>s")
|
42
|
+
# => "39.3701 in"
|
43
|
+
#
|
44
|
+
# @param [String, optional] format
|
45
|
+
# The custom format string for formatting the measurement. If not provided,
|
46
|
+
# +DEFAULT_FORMAT+ is used.
|
47
|
+
#
|
48
|
+
# @return [String] A formatted string representing the measurement.
|
49
|
+
#
|
50
|
+
# @see DEFAULT_FORMAT
|
51
|
+
# @author {Harshal V. Ladhe}[https://shivam091.github.io/]
|
52
|
+
# @since 5.10.0
|
53
|
+
def to_fs(format = nil)
|
54
|
+
kwargs = {quantity: quantity, unit: unit.to_s}
|
55
|
+
(format || DEFAULT_FORMAT) % kwargs
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,120 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
# -*- frozen_string_literal: true -*-
|
3
|
+
# -*- warn_indent: true -*-
|
4
|
+
|
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
|
15
|
+
module Math
|
16
|
+
# Rounds quantity of the measurement. If +ndigits+ is not specified, quantity
|
17
|
+
# is rounded to +Integer+.
|
18
|
+
#
|
19
|
+
# @example
|
20
|
+
# UnitMeasurements::Length.new(17.625, "m").round
|
21
|
+
# => 18 m
|
22
|
+
#
|
23
|
+
# UnitMeasurements::Length.new(17.625, "m").round(2)
|
24
|
+
# => 17.63 m
|
25
|
+
#
|
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
|
32
|
+
def round(ndigits = 0)
|
33
|
+
self.class.new(quantity.round(ndigits), unit)
|
34
|
+
end
|
35
|
+
|
36
|
+
# Returns absolute value of the measurement quantity.
|
37
|
+
#
|
38
|
+
# @example
|
39
|
+
# UnitMeasurements::Length.new(-17.625, "m").abs
|
40
|
+
# => 17.625 m
|
41
|
+
#
|
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
|
47
|
+
def abs
|
48
|
+
self.class.new(quantity.abs, unit)
|
49
|
+
end
|
50
|
+
|
51
|
+
# Returns floored quantity of the measurement. If +ndigits+ is not specified,
|
52
|
+
# quantity is rounded to next lower +Integer+.
|
53
|
+
#
|
54
|
+
# @example
|
55
|
+
# UnitMeasurements::Length.new(17.625, "m").floor
|
56
|
+
# => 17 m
|
57
|
+
#
|
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)
|
69
|
+
end
|
70
|
+
|
71
|
+
# Returns ceiled quantity of the measurement. If +ndigits+ is not specified,
|
72
|
+
# quantity is rounded to next higher +Integer+.
|
73
|
+
#
|
74
|
+
# @example
|
75
|
+
# UnitMeasurements::Length.new(17.625, "m").ceil
|
76
|
+
# => 18 m
|
77
|
+
#
|
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)
|
89
|
+
end
|
90
|
+
|
91
|
+
# Returns square root of the measurement quantity.
|
92
|
+
#
|
93
|
+
# @example
|
94
|
+
# UnitMeasurements::Length.new(9, "m").sqrt
|
95
|
+
# => 3.0 m
|
96
|
+
#
|
97
|
+
# @return [Measurement] A new +Measurement+ instance with square root of quantity.
|
98
|
+
#
|
99
|
+
# @author {Harshal V. Ladhe}[https://shivam091.github.io/]
|
100
|
+
# @since 5.13.0
|
101
|
+
def sqrt
|
102
|
+
self.class.new((quantity ** Rational(1, 2)), unit)
|
103
|
+
end
|
104
|
+
|
105
|
+
# Returns cube root of the measurement quantity.
|
106
|
+
#
|
107
|
+
# @example
|
108
|
+
# UnitMeasurements::Length.new(27, "m").cbrt
|
109
|
+
# => 3.0 m
|
110
|
+
#
|
111
|
+
# @return [Measurement]
|
112
|
+
# A new +Measurement+ instance with cube root of quantity.
|
113
|
+
#
|
114
|
+
# @author {Harshal V. Ladhe}[https://shivam091.github.io/]
|
115
|
+
# @since 5.13.0
|
116
|
+
def cbrt
|
117
|
+
self.class.new((quantity ** Rational(1, 3)), unit)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|