unit_measurements 5.12.0 → 5.14.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: e01978467f274548e8cf792d9b7bfe26ab85155a2c099482cb8b4017641ed900
4
- data.tar.gz: d09990112a19291527059e822906a802a051541b654babad13e97110c5557dea
3
+ metadata.gz: d59abc6cd3128c515be37c2e7bcc40cbbaa73530a4a5ed1ce6d5e7093202e063
4
+ data.tar.gz: 22091e2ce789b4a064fb0f06fb704805b69cc86601334ab4d9f8a7afe9c6a0fd
5
5
  SHA512:
6
- metadata.gz: 0faa94f0a962f19134ff58276c6c876a30a81817172039c4261eaa9a15eeb61dd7047f61b96168c2115c4ba40711fee42cb4ceb832c6e6640bd9c8e7e0f4343b
7
- data.tar.gz: d9213995299feeb51dda98cc4dbbd3bd76f6c4782a8e04b9612cc7f3134b192c74aa80b027779c1b8c862358a84a8c40469753a086ceb94fd5b5ee2b8d33e973
6
+ metadata.gz: 4e16e3e25e06d155664fab616cf4e3147d75cf4aef71c15c6312572418fd124d11436c402fbe7e83e984e483c737a073ad180947f0ee071fab170a59c8f880a4
7
+ data.tar.gz: b6e6bd19810a115b48d7107859b82e21d8b5dc231455d8a995a9ea5157c44d38c53c287a15945a342f1b376fcfe80b539de29ad1be9ca112e5750ac866013cbc
data/CHANGELOG.md CHANGED
@@ -1,3 +1,22 @@
1
+ ## [5.14.0](https://github.com/shivam091/unit_measurements/compare/v5.13.0...v5.14.0) - 2023-11-29
2
+
3
+ ### What's new
4
+
5
+ - Added `.define_numeric_methods` support to define numeric extension methods for units.
6
+
7
+ ----------
8
+
9
+ ## [5.13.0](https://github.com/shivam091/unit_measurements/compare/v5.12.0...v5.13.0) - 2023-11-27
10
+
11
+ ### What's new
12
+
13
+ - Added `Measurement#to_primitive` to convert the measurement to the primitive unit.
14
+ - Added `#cbrt` method to calculate cube root of the measurement quantity.
15
+ - Added `#sqrt` method to calculate square root of the measurement quantity.
16
+ - Aliased `#to_primitive` method as `#in_primitive` and `#as_primitive`.
17
+
18
+ ----------
19
+
1
20
  ## [5.12.0](https://github.com/shivam091/unit_measurements/compare/v5.11.1...v5.12.0) - 2023-11-25
2
21
 
3
22
  ### What's new
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- unit_measurements (5.12.0)
4
+ unit_measurements (5.14.0)
5
5
  activesupport (~> 7.0)
6
6
 
7
7
  GEM
data/README.md CHANGED
@@ -116,10 +116,12 @@ UnitMeasurements::Length.new(1, "km").convert_to!("m")
116
116
  You can convert the measurement directly to the `primitive` unit of the unit group as:
117
117
 
118
118
  ```ruby
119
- UnitMeasurements::Length.new(1, "cm").convert_to("primitive")
119
+ UnitMeasurements::Length.new(1, "cm").to_primitive
120
120
  #=> 0.01 m
121
121
  ```
122
122
 
123
+ Note: `#to_primitive` method is aliased as `#in_primitive` and `#as_primitive`.
124
+
123
125
  **Parse string without having to split out the quantity and source unit:**
124
126
 
125
127
  This method provides `use_cache` parameter which defaults to `false` to indicate whether the caching of conversion factors should happen.
@@ -444,7 +446,7 @@ unit group using the `primitive` method. You can specify cache file name in unit
444
446
 
445
447
  ```ruby
446
448
  UnitMeasurements::MyUnitGroup = UnitMeasurements.build do
447
- # Set primitive unit for the unit group (optional).
449
+ # Set primitive unit for the unit group.
448
450
  primitive "s"
449
451
 
450
452
  # Group units by the unit system (optional).
@@ -480,6 +482,31 @@ Length = UnitMeasurements::Length
480
482
  Volume = UnitMeasurements::Volume
481
483
  ```
482
484
 
485
+ ## Extras
486
+
487
+ ### Numeric extension methods
488
+
489
+ The `.define_numeric_methods` method allows you to instantiate measurements in a
490
+ manner similar to how `ActiveSupport::Duration` objects are created in Rails,
491
+ providing a familiar syntax and functionality.
492
+
493
+ To define numeric extension methods for specific units within a unit group, use
494
+ the following syntax:
495
+
496
+ ```ruby
497
+ UnitMeasurements::Length.define_numeric_methods("metre", "foot", "inch")
498
+ ```
499
+
500
+ This will enable the usage of these units as methods to instantiate and use measurements:
501
+
502
+ ```ruby
503
+ 1.m #=> Instantiate a measurement representing 1 metre.
504
+ 5.feet #=> Instantiate a measurement representing 5 feet.
505
+ 10.inches #=> Instantiate a measurement representing 10 inches.
506
+ 1.foot == 12.inches #=> equality comparison between two measurements.
507
+ 1.ft + 12.in #=> adds quantity of two measurements.
508
+ ```
509
+
483
510
  ## Contributing
484
511
 
485
512
  1. Fork it
@@ -151,6 +151,8 @@ module UnitMeasurements
151
151
  end
152
152
 
153
153
  # The following requires load various components of the unit measurements library.
154
+ require "unit_measurements/extras/numeric_methods"
155
+
154
156
  require "unit_measurements/configuration"
155
157
  require "unit_measurements/cache"
156
158
  require "unit_measurements/unit_group_builder"
@@ -0,0 +1,81 @@
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+ extension 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.
9
+ #
10
+ # This module is included in the +Measurement+ class to allow defining numeric
11
+ # extension 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+ extension methods for specified units within the unit
20
+ # group. If units are empty, it defaults to defining methods for all units
21
+ # within the unit group.
22
+ #
23
+ # @param [Array<String|Symbol>] units
24
+ # An array of units' names for which numeric methods need to be defined.
25
+ # If empty, methods will be defined for all units in the unit group.
26
+ #
27
+ # @return [Array<Unit>] An array of units for which methods are defined.
28
+ #
29
+ # @example Define numeric methods for metres, centimetres, and millimetres:
30
+ # UnitMeasurements::Length.define_numeric_methods("metres", :cm, :mm)
31
+ #
32
+ # @example Define numeric methods for all units in the unit group:
33
+ # UnitMeasurements::Length.define_numeric_methods
34
+ #
35
+ # @see #define_numeric_method_for
36
+ #
37
+ # @author {Harshal V. Ladhe}[https://shivam091.github.io/]
38
+ # @since 5.14.0
39
+ def define_numeric_methods(*units)
40
+ unit_group = self
41
+ units = units.empty? ? unit_group.units : units
42
+
43
+ units.inject([]) do |units, unit|
44
+ units << define_numeric_method_for(unit, unit_group)
45
+ end
46
+ end
47
+
48
+ private
49
+
50
+ # @private
51
+ # @scope class
52
+ # This method defines a numeric method for a specific unit within a unit group.
53
+ # The method is defined dynamically using +define_method+ and associates the
54
+ # unit with the numeric value.
55
+ #
56
+ # @param [String|Symbol|Unit] unit
57
+ # The unit for which the numeric method is defined.
58
+ # @param [UnitGroup] unit_group The unit group to which the unit belongs.
59
+ #
60
+ # @return [Unit] The unit instance for which the method was defined.
61
+ #
62
+ # @see #define_numeric_methods
63
+ #
64
+ # @author {Harshal V. Ladhe}[https://shivam091.github.io/]
65
+ # @since 5.14.0
66
+ def define_numeric_method_for(unit, unit_group)
67
+ unit = unit.is_a?(Unit) ? unit : unit_group.unit_for!(unit)
68
+
69
+ unit.names.each do |method_name|
70
+ # Check if the name contains alphabetic characters
71
+ next unless method_name =~ /^[a-zA-Z]+$/
72
+
73
+ Numeric.define_method(method_name) do
74
+ unit_group.new(self, unit)
75
+ end
76
+ end
77
+
78
+ unit
79
+ end
80
+ end
81
+ end
@@ -87,5 +87,34 @@ module UnitMeasurements
87
87
  def ceil(ndigits = 0)
88
88
  self.class.new(quantity.ceil(ndigits), unit)
89
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
90
119
  end
91
120
  end
@@ -23,6 +23,7 @@ module UnitMeasurements
23
23
  # @see Conversion
24
24
  # @see Formatter
25
25
  # @see Math
26
+ # @see NumericMethods
26
27
  # @author {Harshal V. Ladhe}[https://shivam091.github.io/]
27
28
  # @since 1.0.0
28
29
  class Measurement
@@ -32,6 +33,8 @@ module UnitMeasurements
32
33
  include Formatter
33
34
  include Math
34
35
 
36
+ extend NumericMethods
37
+
35
38
  # Regular expression to match conversion strings.
36
39
  #
37
40
  # @author {Harshal V. Ladhe}[https://shivam091.github.io/]
@@ -131,15 +134,11 @@ module UnitMeasurements
131
134
  # UnitMeasurements::Length.new(1, "m").convert_to("cm")
132
135
  # => 100.0 cm
133
136
  #
134
- # UnitMeasurements::Length.new(1, "cm").convert_to("primitive")
135
- # => 0.01 m
136
- #
137
- # UnitMeasurements::Length.new(1, "m").convert_to("cm", use_cache: true)
138
- # => 100.0 cm
137
+ # UnitMeasurements::Length.new(1, "m").convert_to("mm", use_cache: true)
138
+ # => 1000.0 cm
139
139
  #
140
140
  # @param [String|Symbol] target_unit
141
- # The target unit for conversion. Specifing +primitive+ will convert the
142
- # measurement to a primitive unit of the unit group.
141
+ # The target unit for conversion.
143
142
  # @param [TrueClass|FalseClass] use_cache
144
143
  # Indicates whether to use cached conversion factors.
145
144
  #
@@ -147,20 +146,10 @@ module UnitMeasurements
147
146
  # A new +Measurement+ instance with the converted +quantity+ and
148
147
  # +target unit+.
149
148
  #
150
- # @raise [MissingPrimitiveUnitError]
151
- # if primitive unit is not set for the unit group.
152
- #
153
149
  # @author {Harshal V. Ladhe}[https://shivam091.github.io/]
154
150
  # @since 1.0.0
155
151
  def convert_to(target_unit, use_cache: false)
156
- target_unit = if target_unit.to_s.eql?("primitive")
157
- primitive_unit = self.class.primitive
158
-
159
- raise MissingPrimitiveUnitError if primitive_unit.nil?
160
- primitive_unit
161
- else
162
- unit_from_unit_or_name!(target_unit)
163
- end
152
+ target_unit = unit_from_unit_or_name!(target_unit)
164
153
  return self if target_unit == unit
165
154
 
166
155
  conversion_factor = calculate_conversion_factor(target_unit, use_cache)
@@ -177,15 +166,11 @@ module UnitMeasurements
177
166
  # UnitMeasurements::Length.new(1, "m").convert_to!("cm")
178
167
  # => 100.0 cm
179
168
  #
180
- # UnitMeasurements::Length.new(1, "cm").convert_to!("primitive")
181
- # => 0.01 m
182
- #
183
- # UnitMeasurements::Length.new(1, "m").convert_to!("cm", use_cache: true)
184
- # => 100.0 cm
169
+ # UnitMeasurements::Length.new(1, "m").convert_to!("mm", use_cache: true)
170
+ # => 1000.0 mm
185
171
  #
186
172
  # @param [String|Symbol] target_unit
187
- # The target unit for conversion. Specifing +primitive+ will convert the
188
- # measurement to a primitive unit of the unit group.
173
+ # The target unit for conversion.
189
174
  # @param [TrueClass|FalseClass] use_cache
190
175
  # Indicates whether to use cached conversion factors.
191
176
  #
@@ -205,6 +190,41 @@ module UnitMeasurements
205
190
  alias_method :in!, :convert_to!
206
191
  alias_method :as!, :convert_to!
207
192
 
193
+ # Converts the measurement to its primitive unit and returns a new instance
194
+ # of the +Measurement+.
195
+ #
196
+ # The method first retrieves the primitive unit of the unit group associated
197
+ # with the measurement. If the primitive unit is not set, it raises a
198
+ # +MissingPrimitiveUnitError+.
199
+ #
200
+ # @example
201
+ # UnitMeasurements::Length.new(1, "m").to_primitive
202
+ # => 1 m
203
+ #
204
+ # UnitMeasurements::Length.new(1, "cm").to_primitive
205
+ # => 0.01 m
206
+ #
207
+ # @param [TrueClass|FalseClass] use_cache
208
+ # Indicates whether to use cached conversion factors.
209
+ # @return [Measurement]
210
+ # A new +Measurement+ instance representing the measurement in its
211
+ # primitive unit.
212
+ #
213
+ # @raise [MissingPrimitiveUnitError]
214
+ # If the primitive unit is not set for the unit group associated with the
215
+ # measurement.
216
+ #
217
+ # @author {Harshal V. Ladhe}[https://shivam091.github.io/]
218
+ # @since 5.13.0
219
+ def to_primitive(use_cache: false)
220
+ primitive_unit = self.class.primitive
221
+ raise MissingPrimitiveUnitError if primitive_unit.nil?
222
+
223
+ convert_to(primitive_unit, use_cache: use_cache)
224
+ end
225
+ alias_method :in_primitive, :to_primitive
226
+ alias_method :as_primitive, :to_primitive
227
+
208
228
  # Returns an object representation of the +Measurement+.
209
229
  #
210
230
  # @param [TrueClass|FalseClass] dump If +true+, returns the dump representation.
@@ -4,5 +4,5 @@
4
4
 
5
5
  module UnitMeasurements
6
6
  # Current stable version.
7
- VERSION = "5.12.0"
7
+ VERSION = "5.14.0"
8
8
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: unit_measurements
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.12.0
4
+ version: 5.14.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Harshal LADHE
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-11-25 00:00:00.000000000 Z
11
+ date: 2023-11-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -118,6 +118,7 @@ files:
118
118
  - lib/unit_measurements/errors/primitive_unit_already_set_error.rb
119
119
  - lib/unit_measurements/errors/unit_already_defined_error.rb
120
120
  - lib/unit_measurements/errors/unit_error.rb
121
+ - lib/unit_measurements/extras/numeric_methods.rb
121
122
  - lib/unit_measurements/formatter.rb
122
123
  - lib/unit_measurements/math.rb
123
124
  - lib/unit_measurements/measurement.rb