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.
Files changed (91) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/main.yml +31 -0
  3. data/.github/workflows/pages.yml +31 -0
  4. data/.gitignore +12 -0
  5. data/.rspec +3 -0
  6. data/.yardopts +2 -0
  7. data/CHANGELOG.md +645 -0
  8. data/Gemfile +7 -0
  9. data/Gemfile.lock +56 -0
  10. data/LICENSE.md +21 -0
  11. data/README.md +511 -0
  12. data/Rakefile +10 -0
  13. data/lib/unit_measurements/arithmetic.rb +225 -0
  14. data/lib/unit_measurements/base.rb +177 -0
  15. data/lib/unit_measurements/cache.rb +173 -0
  16. data/lib/unit_measurements/comparison.rb +64 -0
  17. data/lib/unit_measurements/configuration.rb +64 -0
  18. data/lib/unit_measurements/conversion.rb +92 -0
  19. data/lib/unit_measurements/errors/blank_quantity_error.rb +21 -0
  20. data/lib/unit_measurements/errors/blank_unit_error.rb +21 -0
  21. data/lib/unit_measurements/errors/missing_primitive_unit_error.rb +24 -0
  22. data/lib/unit_measurements/errors/parse_error.rb +37 -0
  23. data/lib/unit_measurements/errors/primitive_unit_already_set_error.rb +22 -0
  24. data/lib/unit_measurements/errors/unit_already_defined_error.rb +37 -0
  25. data/lib/unit_measurements/errors/unit_error.rb +36 -0
  26. data/lib/unit_measurements/extras/conversion_methods.rb +87 -0
  27. data/lib/unit_measurements/extras/numeric_methods.rb +85 -0
  28. data/lib/unit_measurements/formatter.rb +58 -0
  29. data/lib/unit_measurements/math.rb +120 -0
  30. data/lib/unit_measurements/measurement.rb +539 -0
  31. data/lib/unit_measurements/normalizer.rb +155 -0
  32. data/lib/unit_measurements/parser.rb +220 -0
  33. data/lib/unit_measurements/unit.rb +243 -0
  34. data/lib/unit_measurements/unit_group.rb +297 -0
  35. data/lib/unit_measurements/unit_group_builder.rb +224 -0
  36. data/lib/unit_measurements/unit_groups/acceleration.rb +36 -0
  37. data/lib/unit_measurements/unit_groups/all.rb +56 -0
  38. data/lib/unit_measurements/unit_groups/amount_of_substance.rb +13 -0
  39. data/lib/unit_measurements/unit_groups/angular_acceleration.rb +14 -0
  40. data/lib/unit_measurements/unit_groups/angular_velocity.rb +25 -0
  41. data/lib/unit_measurements/unit_groups/area.rb +49 -0
  42. data/lib/unit_measurements/unit_groups/catalytic_activity.rb +13 -0
  43. data/lib/unit_measurements/unit_groups/density.rb +33 -0
  44. data/lib/unit_measurements/unit_groups/dynamic_viscosity.rb +22 -0
  45. data/lib/unit_measurements/unit_groups/electric_charge.rb +20 -0
  46. data/lib/unit_measurements/unit_groups/electric_conductance.rb +15 -0
  47. data/lib/unit_measurements/unit_groups/electric_current.rb +19 -0
  48. data/lib/unit_measurements/unit_groups/electric_dipole_moment.rb +13 -0
  49. data/lib/unit_measurements/unit_groups/electric_potential.rb +17 -0
  50. data/lib/unit_measurements/unit_groups/electric_quadrupole_moment.rb +14 -0
  51. data/lib/unit_measurements/unit_groups/electrical_capacitance.rb +15 -0
  52. data/lib/unit_measurements/unit_groups/electrical_elastance.rb +13 -0
  53. data/lib/unit_measurements/unit_groups/electrical_inductance.rb +15 -0
  54. data/lib/unit_measurements/unit_groups/electrical_resistance.rb +16 -0
  55. data/lib/unit_measurements/unit_groups/energy.rb +58 -0
  56. data/lib/unit_measurements/unit_groups/force.rb +47 -0
  57. data/lib/unit_measurements/unit_groups/frequency.rb +16 -0
  58. data/lib/unit_measurements/unit_groups/illuminance.rb +18 -0
  59. data/lib/unit_measurements/unit_groups/information_entropy.rb +15 -0
  60. data/lib/unit_measurements/unit_groups/kinetic_viscosity.rb +18 -0
  61. data/lib/unit_measurements/unit_groups/length.rb +67 -0
  62. data/lib/unit_measurements/unit_groups/luminance.rb +21 -0
  63. data/lib/unit_measurements/unit_groups/luminous_flux.rb +11 -0
  64. data/lib/unit_measurements/unit_groups/luminous_intensity.rb +13 -0
  65. data/lib/unit_measurements/unit_groups/magnetic_field.rb +13 -0
  66. data/lib/unit_measurements/unit_groups/magnetic_flux.rb +15 -0
  67. data/lib/unit_measurements/unit_groups/magnetic_induction.rb +13 -0
  68. data/lib/unit_measurements/unit_groups/magnetomotive_force.rb +13 -0
  69. data/lib/unit_measurements/unit_groups/mass_flow_rate.rb +49 -0
  70. data/lib/unit_measurements/unit_groups/plane_angle.rb +30 -0
  71. data/lib/unit_measurements/unit_groups/power.rb +54 -0
  72. data/lib/unit_measurements/unit_groups/pressure.rb +60 -0
  73. data/lib/unit_measurements/unit_groups/quantity.rb +14 -0
  74. data/lib/unit_measurements/unit_groups/radiation_absorbed_dose.rb +14 -0
  75. data/lib/unit_measurements/unit_groups/radiation_equivalent_dose.rb +13 -0
  76. data/lib/unit_measurements/unit_groups/radiation_exposure.rb +15 -0
  77. data/lib/unit_measurements/unit_groups/radioactivity.rb +14 -0
  78. data/lib/unit_measurements/unit_groups/solid_angle.rb +18 -0
  79. data/lib/unit_measurements/unit_groups/sound_level.rb +13 -0
  80. data/lib/unit_measurements/unit_groups/temperature.rb +19 -0
  81. data/lib/unit_measurements/unit_groups/time.rb +29 -0
  82. data/lib/unit_measurements/unit_groups/torque.rb +40 -0
  83. data/lib/unit_measurements/unit_groups/velocity.rb +37 -0
  84. data/lib/unit_measurements/unit_groups/volume.rb +67 -0
  85. data/lib/unit_measurements/unit_groups/volumetric_flow_rate.rb +35 -0
  86. data/lib/unit_measurements/unit_groups/weight.rb +55 -0
  87. data/lib/unit_measurements/version.rb +8 -0
  88. data/lib/unit_measurements.rb +7 -0
  89. data/unit_measurements.gemspec +43 -0
  90. data/units.md +843 -0
  91. 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