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.
@@ -5,9 +5,54 @@
5
5
  require "set"
6
6
 
7
7
  module UnitMeasurements
8
+ # The +UnitMeasurements::Unit+ class represents a unit of measurement and
9
+ # provides methods to interact with its properties and conversion factors.
10
+ #
11
+ # @author {Harshal V. Ladhe}[https://shivam091.github.io/]
12
+ # @since 1.0.0
8
13
  class Unit
9
- attr_reader :name, :value, :aliases, :system, :unit_group
14
+ # The name of the unit.
15
+ #
16
+ # @author {Harshal V. Ladhe}[https://shivam091.github.io/]
17
+ # @since 1.0.0
18
+ attr_reader :name
10
19
 
20
+ # The conversion value of the unit. It can be a numeric value or a string in
21
+ # the form of a number followed by a unit name (e.g., “10 m”).
22
+ #
23
+ # @author {Harshal V. Ladhe}[https://shivam091.github.io/]
24
+ # @since 1.0.0
25
+ attr_reader :value
26
+
27
+ # A set of alternative names for the unit.
28
+ #
29
+ # @author {Harshal V. Ladhe}[https://shivam091.github.io/]
30
+ # @since 1.0.0
31
+ attr_reader :aliases
32
+
33
+ # The system to which the unit belongs (e.g., “metric”, “imperial”).
34
+ #
35
+ # @author {Harshal V. Ladhe}[https://shivam091.github.io/]
36
+ # @since 4.0.0
37
+ attr_reader :system
38
+
39
+ # The unit group to which the unit belongs.
40
+ #
41
+ # @author {Harshal V. Ladhe}[https://shivam091.github.io/]
42
+ # @since 1.0.0
43
+ attr_reader :unit_group
44
+
45
+ # Initializes a new +Unit+ instance.
46
+ #
47
+ # @param [String|Symbol] name The name of the unit.
48
+ # @param [String|Numeric] value The conversion value of the unit.
49
+ # @param [Array<String|Symbol>] aliases Alternative names for the unit.
50
+ # @param [String|Symbol|NilClass] system The system to which the unit belongs.
51
+ # @param [UnitGroup|NilClass] unit_group The unit group to which the unit belongs.
52
+ #
53
+ # @see UnitGroup
54
+ # @author {Harshal V. Ladhe}[https://shivam091.github.io/]
55
+ # @since 1.0.0
11
56
  def initialize(name, value:, aliases:, system:, unit_group: nil)
12
57
  @name = name.to_s.freeze
13
58
  @value = value
@@ -16,6 +61,19 @@ module UnitMeasurements
16
61
  @unit_group = unit_group
17
62
  end
18
63
 
64
+ # Returns a new +Unit+ instance with specified attributes.
65
+ #
66
+ # @param [String|Symbol] name The new name of the unit.
67
+ # @param [String|Numeric] value The new conversion value of the unit.
68
+ # @param [Set<String>] aliases New alternative names for the unit.
69
+ # @param [String|Symbol|NilClass] system The new system to which the unit belongs.
70
+ # @param [UnitGroup|NilClass] unit_group The new unit group to which the unit belongs.
71
+ #
72
+ # @return [Unit] A new unit with specified parameters.
73
+ #
74
+ # @see UnitGroup
75
+ # @author {Harshal V. Ladhe}[https://shivam091.github.io/]
76
+ # @since 1.0.0
19
77
  def with(name: nil, value: nil, aliases: nil, system: nil, unit_group: nil)
20
78
  self.class.new(
21
79
  (name || self.name),
@@ -26,19 +84,58 @@ module UnitMeasurements
26
84
  )
27
85
  end
28
86
 
87
+ # Returns an array containing the name of the unit and its aliases, sorted
88
+ # alphabetically.
89
+ #
90
+ # @example
91
+ # UnitMeasurements::Length.new(1, "m").unit.names
92
+ # => ["m", "meter", "meters", "metre", "metres"]
93
+ #
94
+ # @return [Array<String>] An array of unit names.
95
+ #
96
+ # @author {Harshal V. Ladhe}[https://shivam091.github.io/]
97
+ # @since 1.0.0
29
98
  def names
30
99
  (aliases + [name]).sort.freeze
31
100
  end
32
101
 
102
+ # Returns the name of the unit as a string.
103
+ #
104
+ # @example
105
+ # UnitMeasurements::Length.new(1, "m").unit.to_s
106
+ # => "m"
107
+ #
108
+ # @return [String] The name of the unit.
109
+ #
110
+ # @author {Harshal V. Ladhe}[https://shivam091.github.io/]
111
+ # @since 1.0.0
33
112
  def to_s
34
113
  name
35
114
  end
36
115
 
116
+ # Returns an object representation of the unit, including its aliases if present.
117
+ #
118
+ # @return [Object] An object representation of the +unit+.
119
+ #
120
+ # @author {Harshal V. Ladhe}[https://shivam091.github.io/]
121
+ # @since 1.0.0
37
122
  def inspect
38
123
  aliases = "(#{@aliases.join(", ")})" if @aliases.any?
39
124
  "#<#{self.class.name}: #{name} #{aliases}>"
40
125
  end
41
126
 
127
+ # Calculates the conversion factor for the unit. This method is recursively
128
+ # invoked to calculate the conversion factor of the unit, if unit conversion
129
+ # +value+ is specified with respect to the other unit.
130
+ #
131
+ # This method uses +parse_value+ method to extract the conversion value and
132
+ # the unit.
133
+ #
134
+ # @return [Numeric] The conversion factor as a numeric value.
135
+ #
136
+ # @see #parse_value
137
+ # @author {Harshal V. Ladhe}[https://shivam091.github.io/]
138
+ # @since 1.0.0
42
139
  def conversion_factor
43
140
  return value if value.is_a?(Numeric)
44
141
 
@@ -50,6 +147,10 @@ module UnitMeasurements
50
147
 
51
148
  private
52
149
 
150
+ # Decimal prefixes for SI units.
151
+ #
152
+ # @author {Harshal V. Ladhe}[https://shivam091.github.io/]
153
+ # @since 1.0.0
53
154
  SI_DECIMAL_PREFIXES = [
54
155
  ["q", %w(quecto), 1e-30],
55
156
  ["r", %w(ronto), 1e-27],
@@ -77,6 +178,32 @@ module UnitMeasurements
77
178
  ["Q", %w(quetta), 1e+30]
78
179
  ].map(&:freeze).freeze
79
180
 
181
+ # Parses tokens and returns a +conversion value+ and the +unit+.
182
+ #
183
+ # This method is used internally to parse the conversion value of the unit
184
+ # while calculating the conversion factor. It handles cases where the value
185
+ # can be provided as a string or an array containing a number and a unit.
186
+ #
187
+ # For example, if the value is provided as a string in the form of "10 m",
188
+ # it will be parsed to return 10.0 as the conversion value and "m" as the
189
+ # unit.
190
+ #
191
+ # This method returns conversion value in +rational+ number to avoid precision
192
+ # errors and frozen string of unit name.
193
+ #
194
+ # @param [String|Array] tokens
195
+ # The value to be parsed. It can be either a string or an array containing
196
+ # a number and a unit.
197
+ #
198
+ # @return [Array<Numeric, String>] The array of conversion value and the unit.
199
+ #
200
+ # @raise [BaseError]
201
+ # if +tokens+ is not an instance of +Array+ or +String+, or +tokens+ array
202
+ # contains more than two elements.
203
+ #
204
+ # @see #conversion_factor
205
+ # @author {Harshal V. Ladhe}[https://shivam091.github.io/]
206
+ # @since 1.2.0
80
207
  def parse_value(tokens)
81
208
  case tokens
82
209
  when String
@@ -3,18 +3,89 @@
3
3
  # -*- warn_indent: true -*-
4
4
 
5
5
  module UnitMeasurements
6
+ # The +UnitMeasurements::UnitGroup+ class provides a collection of units with
7
+ # methods to retrieve units by name, check if a unit is defined, and much more.
8
+ #
9
+ # It serves as a container for organizing and working with units within the
10
+ # unit group.
11
+ #
12
+ # @author {Harshal V. Ladhe}[https://shivam091.github.io/]
13
+ # @since 1.0.0
6
14
  class UnitGroup
7
- attr_reader :primitive, :units
15
+ # The primitive unit of the unit group.
16
+ #
17
+ # @example
18
+ # UnitMeasurements::Length.primitive
19
+ # => #<UnitMeasurements::Unit: m (meter, meters, metre, metres)>
20
+ #
21
+ # @return [Unit] The primitive unit of the unit group.
22
+ #
23
+ # @author {Harshal V. Ladhe}[https://shivam091.github.io/]
24
+ # @since 1.0.0
25
+ attr_reader :primitive
8
26
 
27
+ # An array of units within the unit group.
28
+ #
29
+ # @example
30
+ # UnitMeasurements::Length.units
31
+ # => [#<UnitMeasurements::Unit: m (meter, meters, metre, metres)>, ...]
32
+ #
33
+ # @author {Harshal V. Ladhe}[https://shivam091.github.io/]
34
+ # @since 1.0.0
35
+ attr_reader :units
36
+
37
+ # Initializes a new +UnitGroup+ instance.
38
+ #
39
+ # @param [String|Symbol, optional] primitive The name of the primitive unit.
40
+ # @param [Array<Unit>] units An array of +Unit+ instances.
41
+ #
42
+ # @author {Harshal V. Ladhe}[https://shivam091.github.io/]
43
+ # @since 1.0.0
9
44
  def initialize(primitive, units)
10
45
  @units = units.map { |unit| unit.with(unit_group: self) }
11
46
  @primitive = unit_for!(primitive) if primitive
12
47
  end
13
48
 
49
+ # Returns the unit instance for a given unit name. It returns +nil+ if unit
50
+ # is not defined within the unit group.
51
+ #
52
+ # @example
53
+ # UnitMeasurements::Length.unit_for("m")
54
+ # => #<UnitMeasurements::Unit: m (meter, meters, metre, metres)>
55
+ #
56
+ # UnitMeasurements::Length.unit_for("z")
57
+ # => nil
58
+ #
59
+ # @param [String|Symbol] name The name of the unit.
60
+ #
61
+ # @return [Unit|NilClass] A +Unit+ instance or +nil+ if the unit is not found.
62
+ #
63
+ # @author {Harshal V. Ladhe}[https://shivam091.github.io/]
64
+ # @since 1.0.0
14
65
  def unit_for(name)
15
66
  unit_name_to_unit(name)
16
67
  end
17
68
 
69
+ # This method works same as +unit_for+ but it raises +UnitError+ if the
70
+ # unit is not defined within the unit group.
71
+ #
72
+ # @example
73
+ # UnitMeasurements::Length.unit_for!("m")
74
+ # => #<UnitMeasurements::Unit: m (meter, meters, metre, metres)>
75
+ #
76
+ # UnitMeasurements::Length.unit_for!("z")
77
+ # => Invalid unit: 'z'. (UnitMeasurements::UnitError)
78
+ #
79
+ # @param [String|Symbol] name The name of the unit to look for.
80
+ #
81
+ # @return [Unit] A +Unit+ instance.
82
+ #
83
+ # @raise [UnitError] If the unit is not found.
84
+ #
85
+ # @see #unit_for
86
+ # @see UnitError
87
+ # @author {Harshal V. Ladhe}[https://shivam091.github.io/]
88
+ # @since 1.0.0
18
89
  def unit_for!(name)
19
90
  unit = unit_for(name)
20
91
  raise UnitError, name unless unit
@@ -23,32 +94,110 @@ module UnitMeasurements
23
94
  end
24
95
  alias_method :[], :unit_for!
25
96
 
26
- def unit_with_name_and_aliases
27
- units.each_with_object({}) do |unit, hash|
28
- unit.names.each { |name| hash[name.to_s] = unit }
29
- end
30
- end
31
-
97
+ # Returns an array of names of all the units defined within the unit group,
98
+ # sorted alphabetically.
99
+ #
100
+ # @example
101
+ # UnitMeasurements::Length.unit_names
102
+ # => ["ft", "in", "m", "mi", "yd"]
103
+ #
104
+ # @return [Array<String>] An array of unit names.
105
+ #
106
+ # @author {Harshal V. Ladhe}[https://shivam091.github.io/]
107
+ # @since 1.0.0
32
108
  def unit_names
33
109
  units.map(&:name).sort
34
110
  end
35
111
 
112
+ # Returns an array of names and aliases of all the units defined within the
113
+ # unit group, sorted alphabetically.
114
+ #
115
+ # @example
116
+ # UnitMeasurements::Length.unit_names_with_aliases
117
+ # => ["\"", "'", "feet", "foot", "ft", "in", "inch", "inches", "m", "meter", "meters", "metre", "metres", "mi", "mile", "miles", "yard", "yards", "yd"]
118
+ #
119
+ # @return [Array<String>] An array of unit names and aliases.
120
+ #
121
+ # @author {Harshal V. Ladhe}[https://shivam091.github.io/]
122
+ # @since 1.0.0
36
123
  def unit_names_with_aliases
37
124
  units.flat_map(&:names).sort
38
125
  end
39
126
 
40
- def unit_name_to_unit(name)
41
- unit_with_name_and_aliases[name.to_s]
42
- end
43
-
127
+ # Checks if a unit with a given name is defined within the unit group.
128
+ #
129
+ # @example
130
+ # UnitMeasurements::Length.defined?("m")
131
+ # => true
132
+ #
133
+ # UnitMeasurements::Length.defined?("metre")
134
+ # => false
135
+ #
136
+ # @param [String|Symbol] name The name of the unit to look for.
137
+ #
138
+ # @return [TrueClass|FalseClass] +true+
139
+ # if the unit is defined, +false+ otherwise.
140
+ #
141
+ # @author {Harshal V. Ladhe}[https://shivam091.github.io/]
142
+ # @since 1.0.0
44
143
  def defined?(name)
45
144
  unit = unit_for(name)
46
145
 
47
146
  unit ? unit.name == name.to_s : false
48
147
  end
49
148
 
149
+ # Checks if a given name corresponds to a defined unit or an alias of any
150
+ # defined unit.
151
+ #
152
+ # @example
153
+ # UnitMeasurements::Length.unit_or_alias?("m")
154
+ # => true
155
+ #
156
+ # UnitMeasurements::Length.unit_or_alias?("metre")
157
+ # => true
158
+ #
159
+ # @param [String|Symbol] name The name or alias of the unit to look for.
160
+ #
161
+ # @return [TrueClass|FalseClass] +true+
162
+ # if the name corresponds to a unit or alias, +false+ otherwise.
163
+ #
164
+ # @author {Harshal V. Ladhe}[https://shivam091.github.io/]
165
+ # @since 1.0.0
50
166
  def unit_or_alias?(name)
51
167
  !!unit_for(name)
52
168
  end
169
+
170
+ private
171
+
172
+ # @private
173
+ # Returns a hash where keys are unit names (including aliases) and values
174
+ # are corresponding +Unit+ instances.
175
+ #
176
+ # @example
177
+ # UnitMeasurements::Length.unit_with_name_and_aliases
178
+ # => {"m"=>#<UnitMeasurements::Unit: m (meter, meters, metre, metres)>, ...}
179
+ #
180
+ # @return [Hash] A hash containing unit +names+ as keys and +Unit+ objects as values.
181
+ #
182
+ # @author {Harshal V. Ladhe}[https://shivam091.github.io/]
183
+ # @since 1.0.0
184
+ def unit_with_name_and_aliases
185
+ units.each_with_object({}) do |unit, hash|
186
+ unit.names.each { |name| hash[name.to_s] = unit }
187
+ end
188
+ end
189
+
190
+ # @private
191
+ # Returns the +Unit+ instance for a given unit name.
192
+ #
193
+ # @param [String|Symbol] name The name of the unit.
194
+ #
195
+ # @return [Unit|NilClass] A +Unit+ instance or +nil+ if the unit is not found.
196
+ #
197
+ # @author {Harshal V. Ladhe}[https://shivam091.github.io/]
198
+ # @since 1.0.0
199
+ def unit_name_to_unit(name)
200
+ unit_with_name_and_aliases[name.to_s]
201
+ end
53
202
  end
54
203
  end
@@ -3,25 +3,101 @@
3
3
  # -*- warn_indent: true -*-
4
4
 
5
5
  module UnitMeasurements
6
+ # The +UnitMeasurements::UnitGroupBuilder+ class provides a flexible and
7
+ # configurable way to define units and create unit groups with specific systems
8
+ # and primitive unit.
9
+ #
10
+ # It provides methods like +primitive+, +system+, +unit+, and +si_unit+ to define
11
+ # units and their conversions within the unit group.
12
+ #
13
+ # @see UnitGroup
14
+ # @see PrimitiveUnitAlreadySetError
15
+ # @see UnitAlreadyDefinedError
16
+ # @author {Harshal V. Ladhe}[https://shivam091.github.io/]
17
+ # @since 1.0.0
6
18
  class UnitGroupBuilder
19
+ # An array to store the units defined using the builder.
20
+ #
21
+ # @author {Harshal V. Ladhe}[https://shivam091.github.io/]
22
+ # @since 1.0.0
7
23
  attr_reader :units
8
24
 
25
+ # Initializes a new +UnitGroupBuilder+ instance.
26
+ #
27
+ # @author {Harshal V. Ladhe}[https://shivam091.github.io/]
28
+ # @since 1.0.0
9
29
  def initialize
10
30
  @units = []
11
31
  end
12
32
 
33
+ # Defines a +unit+ and adds it to the list of units.
34
+ #
35
+ # @example
36
+ # unit "in", value: "25.4 mm", aliases: ['"', "inch", "inches"]
37
+ #
38
+ # @param [String|Symbol] name The name of the unit.
39
+ # @param [Numeric|String] value The conversion value of the unit.
40
+ # @param [Array<String|Symbol>, optional] aliases An array of alternative names for the unit.
41
+ #
42
+ # @return [Unit] An instance of +Unit+.
43
+ #
44
+ # @see #build_unit
45
+ # @author {Harshal V. Ladhe}[https://shivam091.github.io/]
46
+ # @since 1.0.0
13
47
  def unit(name, value: 1.0, aliases: [])
14
48
  @units << build_unit(name, value: value, aliases: aliases)
15
49
  end
16
50
 
51
+ # Builds a set of +SI units+ and adds them to the list of units. This method
52
+ # defines unit defined using +name+ along with all the SI prefixes.
53
+ #
54
+ # @example
55
+ # si_unit "m", aliases: ["meter", "metre", "meters", "metres"]
56
+ #
57
+ # @param [String|Symbol] name The name of the unit.
58
+ # @param [Numeric|String] value The conversion value of the unit.
59
+ # @param [Array<String|Symbol>, optional] aliases An array of alternative names for the unit.
60
+ #
61
+ # @return [Array<Unit>] An array of +Unit+ instances.
62
+ #
63
+ # @see #build_si_units
64
+ # @author {Harshal V. Ladhe}[https://shivam091.github.io/]
65
+ # @since 1.0.0
17
66
  def si_unit(name, value: 1.0, aliases: [])
18
67
  @units += build_si_units(name, value: value, aliases: aliases)
19
68
  end
20
69
 
70
+ # Constructs and returns a +UnitGroup+ object based on the units defined
71
+ # using the builder.
72
+ #
73
+ # @return [UnitGroup]
74
+ # An instance of +UnitGroup+ containing units and their conversions.
75
+ #
76
+ # @see UnitGroup
77
+ # @author {Harshal V. Ladhe}[https://shivam091.github.io/]
78
+ # @since 1.0.0
21
79
  def build
22
80
  UnitGroup.new(@primitive, @units)
23
81
  end
24
82
 
83
+ # Defines the +unit system+ within the unit group and evaluates the provided
84
+ # block in the context of the builder.
85
+ #
86
+ # This method is used to group multiple units within the certain unit system,
87
+ # viz., metric, imperial, etc.
88
+ #
89
+ # @example Defining an imperial system with inches and feet:
90
+ # system :imperial do
91
+ # unit "in", value: "25.4 mm", aliases: ['"', "inch", "inches"]
92
+ # unit "ft", value: "12 in", aliases: ["'", "foot", "feet"]
93
+ # end
94
+ #
95
+ # @param [String|Symbol] system_name
96
+ # The name of the unit system in which the units are to be grouped.
97
+ # @param block A block of code to be executed in the context of the builder.
98
+ #
99
+ # @author {Harshal V. Ladhe}[https://shivam091.github.io/]
100
+ # @since 4.0.0
25
101
  def system(system_name, &block)
26
102
  @system = system_name
27
103
  instance_eval(&block) if block_given?
@@ -29,6 +105,20 @@ module UnitMeasurements
29
105
  @system = nil
30
106
  end
31
107
 
108
+ # Sets the +primitive+ unit for the unit group. It raises +PrimitiveUnitAlreadySetError+
109
+ # if the primitive unit has already been set for the unit group.
110
+ #
111
+ # @example
112
+ # primitive "m"
113
+ #
114
+ # @param [String|Symbol] primitive The name of the primitive unit.
115
+ #
116
+ # @raise [PrimitiveUnitAlreadySetError]
117
+ # If the primitive unit has already been set for the unit group.
118
+ #
119
+ # @see PrimitiveUnitAlreadySetError
120
+ # @author {Harshal V. Ladhe}[https://shivam091.github.io/]
121
+ # @since 4.0.0
32
122
  def primitive(primitive)
33
123
  raise PrimitiveUnitAlreadySetError if @primitive
34
124
 
@@ -37,6 +127,20 @@ module UnitMeasurements
37
127
 
38
128
  private
39
129
 
130
+ # @private
131
+ # Builds an array of +Unit+ instances with one instance of +Unit+ with name
132
+ # +name+ along with all SI prefixed +Unit+ instances for it.
133
+ #
134
+ # @param [String|Symbol] name The name of the unit.
135
+ # @param [Numeric|String] value The conversion value of the unit.
136
+ # @param [Array<String|Symbol>, optional] aliases
137
+ # An array of alternative names for the unit.
138
+ #
139
+ # @return [Array<Unit>] An array of +Unit+ instances.
140
+ #
141
+ # @see #build_unit
142
+ # @author {Harshal V. Ladhe}[https://shivam091.github.io/]
143
+ # @since 1.0.0
40
144
  def build_si_units(name, value:, aliases:)
41
145
  si_units = [build_unit(name, value: value, aliases: aliases)]
42
146
 
@@ -50,6 +154,19 @@ module UnitMeasurements
50
154
  si_units
51
155
  end
52
156
 
157
+ # @private
158
+ # Builds an instance of +Unit+ with name +name+, and specified conversion
159
+ # value, and alternate names.
160
+ #
161
+ # @param [String|Symbol] name The name of the unit.
162
+ # @param [Numeric|String] value The conversion value of the unit.
163
+ # @param [Array<String|Symbol>, optional] aliases
164
+ # An array of alternative names for the unit.
165
+ #
166
+ # @return [Unit] An instance of +Unit+.
167
+ #
168
+ # @author {Harshal V. Ladhe}[https://shivam091.github.io/]
169
+ # @since 1.0.0
53
170
  def build_unit(name, value:, aliases:)
54
171
  unit = Unit.new(name, value: value, aliases: aliases, system: @system)
55
172
  check_for_duplicate_unit_names!(unit)
@@ -57,6 +174,22 @@ module UnitMeasurements
57
174
  unit
58
175
  end
59
176
 
177
+ # @private
178
+ # Checks for duplicate unit names within the list of units.
179
+ #
180
+ # This method ensures that there are no duplicate unit names within the list
181
+ # of units. If a duplicate name is found, it raises a +UnitAlreadyDefinedError+.
182
+ #
183
+ # This method is used internally by the +UnitGroupBuilder+ class to build units
184
+ # and handle unit definitions.
185
+ #
186
+ # @param [Unit] unit The unit to be checked.
187
+ #
188
+ # @raise [UnitAlreadyDefinedError]
189
+ # If the unit name is already defined in the list of units.
190
+ #
191
+ # @author {Harshal V. Ladhe}[https://shivam091.github.io/]
192
+ # @since 1.0.0
60
193
  def check_for_duplicate_unit_names!(unit)
61
194
  names = @units.flat_map(&:names)
62
195
 
@@ -2,8 +2,6 @@
2
2
  # -*- frozen_string_literal: true -*-
3
3
  # -*- warn_indent: true -*-
4
4
 
5
- ## Fundamental SI units
6
-
7
5
  require_relative "amount_of_substance"
8
6
  require_relative "electric_current"
9
7
  require_relative "length"
@@ -12,8 +10,6 @@ require_relative "temperature"
12
10
  require_relative "time"
13
11
  require_relative "weight"
14
12
 
15
- ## Derived units
16
-
17
13
  require_relative "area"
18
14
  require_relative "volume"
19
15
  require_relative "density"
@@ -50,8 +46,7 @@ require_relative "radioactivity"
50
46
  require_relative "radiation_exposure"
51
47
  require_relative "radiation_absorbed_dose"
52
48
  require_relative "radiation_equivalent_dose"
53
-
54
- ## Other units
49
+ require_relative "information_entropy"
55
50
 
56
51
  require_relative "sound_level"
57
52
  require_relative "plane_angle"
@@ -0,0 +1,15 @@
1
+ # -*- encoding: utf-8 -*-
2
+ # -*- frozen_string_literal: true -*-
3
+ # -*- warn_indent: true -*-
4
+
5
+ UnitMeasurements::InformationEntropy = UnitMeasurements.build do
6
+ primitive "nat"
7
+
8
+ si_unit "b", value: "1 Sh", aliases: ["bit", "bits"]
9
+ si_unit "B", value: [2.pow(3), "b"], aliases: ["byte", "bytes"]
10
+
11
+ unit "Sh", value: [Math.log(2), "nat"], aliases: ["shannon", "shannons"]
12
+ unit "nat", aliases: ["nit", "nepit", "natural unit of information"]
13
+ unit "nybl", value: [2.pow(2), "b"], aliases: ["nibble", "nibbles", "nybble", "nyble"]
14
+ unit "Hart", value: [Math.log(10), "nat"], aliases: ["hartley", "ban", "dit"]
15
+ end
@@ -3,5 +3,6 @@
3
3
  # -*- warn_indent: true -*-
4
4
 
5
5
  module UnitMeasurements
6
- VERSION = "4.8.0"
6
+ # Current stable version.
7
+ VERSION = "4.10.0"
7
8
  end
@@ -2,7 +2,23 @@
2
2
  # -*- frozen_string_literal: true -*-
3
3
  # -*- warn_indent: true -*-
4
4
 
5
+ # The +UnitMeasurements+ module serves as a container for various functionalities
6
+ # related to unit measurements. It provides methods for creating custom unit
7
+ # groups, defining units, performing arithmetic operations, comparison between
8
+ # measurements, conversions, normalization of input strings, parsing measurements
9
+ # from strings, and more. It is a fundamental part of the unit measurements library.
10
+ #
11
+ # @author {Harshal V. Ladhe}[https://shivam091.github.io/]
12
+ # @since 0.1.0
5
13
  module UnitMeasurements
14
+ # This is the base class for custom errors in the +UnitMeasurements+ module.
15
+ #
16
+ # @see ParseError
17
+ # @see PrimitiveUnitAlreadySetError
18
+ # @see UnitAlreadyDefinedError
19
+ # @see UnitError
20
+ # @author {Harshal V. Ladhe}[https://shivam091.github.io/]
21
+ # @since 1.1.0
6
22
  class BaseError < StandardError; end
7
23
  end
8
24
 
@@ -22,6 +22,7 @@ Gem::Specification.new do |spec|
22
22
  spec.metadata["allowed_push_host"] = "https://rubygems.org"
23
23
 
24
24
  spec.metadata["homepage_uri"] = spec.homepage
25
+ spec.metadata["documentation_uri"] = "https://shivam091.github.io/unit_measurements"
25
26
  spec.metadata["source_code_uri"] = "https://github.com/shivam091/unit_measurements"
26
27
  spec.metadata["changelog_uri"] = "https://github.com/shivam091/unit_measurements/blob/main/CHANGELOG.md"
27
28
  spec.metadata["bug_tracker_uri"] = "https://github.com/shivam091/unit_measurements/issues"
data/units.md CHANGED
@@ -553,3 +553,16 @@ These units are defined in `UnitMeasurements::RadiationEquivalentDose`.
553
553
  |:--|:--|:--|
554
554
  | _1_ | _Sv*_ | _sievert, sieverts_ |
555
555
  | 2 | rem | röntgen equivalent man, roentgen equivalent man |
556
+
557
+ ## 48. Information entropy
558
+
559
+ These units are defined in `UnitMeasurements::InformationEntropy`.
560
+
561
+ | # | Name | Aliases |
562
+ |:--|:--|:--|
563
+ | 1 | b* | bit, bits |
564
+ | 2 | B* | byte, bytes |
565
+ | 3 | Sh | shannon, shannons |
566
+ | _4_ | _nat_ | _nit, nepit, natural unit of information_ |
567
+ | 5 | nybl | nibble, nibbles, nybble, nyble |
568
+ | 6 | Hart | hartley, ban, dit |