basic_temperature 0.2.2 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.inch.yml +3 -0
- data/.rubocop.yml +3 -0
- data/CHANGELOG.md +68 -7
- data/README.md +41 -61
- data/bin/console +1 -1
- data/docs/classes/BasicTemperature.html +27 -1129
- data/docs/classes/BasicTemperature/Temperature.html +1239 -0
- data/docs/classes/BasicTemperature/Temperature/AdditionalHelpers.html +78 -0
- data/docs/classes/BasicTemperature/Temperature/Assertions.html +78 -0
- data/docs/classes/BasicTemperature/Temperature/Casting.html +78 -0
- data/docs/classes/BasicTemperature/Temperature/Errors.html +109 -0
- data/docs/classes/BasicTemperature/Temperature/Errors/InitializationArguments.html +94 -0
- data/docs/classes/BasicTemperature/Temperature/Errors/InvalidDegrees.html +94 -0
- data/docs/classes/BasicTemperature/Temperature/Errors/InvalidNumeric.html +94 -0
- data/docs/classes/BasicTemperature/Temperature/Errors/InvalidNumericOrTemperature.html +94 -0
- data/docs/classes/BasicTemperature/Temperature/Errors/InvalidScale.html +94 -0
- data/docs/classes/BasicTemperature/Temperature/Initialization.html +78 -0
- data/docs/classes/BasicTemperature/Temperature/Memoization.html +78 -0
- data/docs/classes/BasicTemperature/Temperature/Rounding.html +78 -0
- data/docs/classes/Object.html +3 -175
- data/docs/created.rid +12 -4
- data/docs/files/lib/basic_temperature/alias_rb.html +73 -0
- data/docs/files/lib/basic_temperature/temperature/additional_helpers_rb.html +94 -0
- data/docs/files/lib/basic_temperature/temperature/assertions_rb.html +94 -0
- data/docs/files/lib/basic_temperature/temperature/casting_rb.html +94 -0
- data/docs/files/lib/basic_temperature/temperature/errors_rb.html +119 -0
- data/docs/files/lib/basic_temperature/temperature/initialization_rb.html +94 -0
- data/docs/files/lib/basic_temperature/temperature/memoization_rb.html +94 -0
- data/docs/files/lib/basic_temperature/temperature/rounding_rb.html +94 -0
- data/docs/files/lib/basic_temperature/temperature_rb.html +17 -1
- data/docs/files/lib/basic_temperature/version_rb.html +2 -2
- data/docs/files/lib/basic_temperature_rb.html +2 -30
- data/docs/js/navigation.js.gz +0 -0
- data/docs/js/search_index.js +1 -1
- data/docs/js/search_index.js.gz +0 -0
- data/docs/js/searcher.js.gz +0 -0
- data/docs/panel/links.html +16 -0
- data/docs/panel/tree.js +1 -1
- data/lib/basic_temperature.rb +3 -700
- data/lib/basic_temperature/alias.rb +5 -0
- data/lib/basic_temperature/temperature.rb +515 -2
- data/lib/basic_temperature/temperature/additional_helpers.rb +17 -0
- data/lib/basic_temperature/temperature/assertions.rb +30 -0
- data/lib/basic_temperature/temperature/casting.rb +19 -0
- data/lib/basic_temperature/temperature/errors.rb +50 -0
- data/lib/basic_temperature/temperature/initialization.rb +32 -0
- data/lib/basic_temperature/temperature/memoization.rb +26 -0
- data/lib/basic_temperature/temperature/rounding.rb +13 -0
- data/lib/basic_temperature/version.rb +2 -2
- metadata +32 -2
@@ -1,5 +1,518 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative '
|
3
|
+
require_relative 'temperature/additional_helpers'
|
4
|
+
require_relative 'temperature/assertions'
|
5
|
+
require_relative 'temperature/casting'
|
6
|
+
require_relative 'temperature/errors'
|
7
|
+
require_relative 'temperature/initialization'
|
8
|
+
require_relative 'temperature/memoization'
|
9
|
+
require_relative 'temperature/rounding'
|
4
10
|
|
5
|
-
|
11
|
+
module BasicTemperature
|
12
|
+
# rubocop:disable Metrics/ClassLength
|
13
|
+
|
14
|
+
##
|
15
|
+
# Temperature is a simple {Value Object}[https://martinfowler.com/bliki/ValueObject.html] for basic
|
16
|
+
# temperature operations like conversions from <tt>Celsius</tt> to <tt>Fahrenhait</tt> or <tt>Kelvin</tt>
|
17
|
+
# etc.
|
18
|
+
#
|
19
|
+
# Supported scales: <tt>Celsius</tt>, <tt>Fahrenheit</tt>, <tt>Kelvin</tt> and <tt>Rankine</tt>.
|
20
|
+
#
|
21
|
+
# == Creating Temperatures
|
22
|
+
#
|
23
|
+
# A new temperature can be created in multiple ways:
|
24
|
+
#
|
25
|
+
# - Using keyword arguments:
|
26
|
+
#
|
27
|
+
# Temperature.new(degrees: 0, scale: :celsius)
|
28
|
+
#
|
29
|
+
# - Using positional arguments:
|
30
|
+
#
|
31
|
+
# Temperature.new(0, :celsius)
|
32
|
+
#
|
33
|
+
# - Even more concise way using <tt>Temperature.[]</tt> (an alias of <tt>Temperature.new</tt>):
|
34
|
+
#
|
35
|
+
# Temperature[0, :celsius]
|
36
|
+
#
|
37
|
+
#
|
38
|
+
# == Creating Temperatures from already existing temperature objects
|
39
|
+
#
|
40
|
+
# Sometimes it is useful to create a new temperature from already existing one.
|
41
|
+
#
|
42
|
+
# For such cases, there are {set_degrees}[rdoc-ref:Temperature#set_degrees] and
|
43
|
+
# {set_scale}[rdoc-ref:Temperature#set_scale].
|
44
|
+
#
|
45
|
+
# Since temperatures are {Value Objects}[https://martinfowler.com/bliki/ValueObject.html], both methods
|
46
|
+
# returns new instances.
|
47
|
+
#
|
48
|
+
# Examples:
|
49
|
+
#
|
50
|
+
# temperature = Temperature[0, :celsius]
|
51
|
+
# # => 0 °C
|
52
|
+
#
|
53
|
+
# new_temperature = temperature.set_degrees(15)
|
54
|
+
# # => 15 °C
|
55
|
+
#
|
56
|
+
# temperature = Temperature[0, :celsius]
|
57
|
+
# # => 0 °C
|
58
|
+
#
|
59
|
+
# new_temperature = temperature.set_scale(:kelvin)
|
60
|
+
# # => 0 K
|
61
|
+
#
|
62
|
+
# == Conversions
|
63
|
+
#
|
64
|
+
# Temperatures can be converted to diffirent scales.
|
65
|
+
#
|
66
|
+
# Currently, the following scales are supported: <tt>Celsius</tt>, <tt>Fahrenheit</tt>, <tt>Kelvin</tt> and
|
67
|
+
# <tt>Rankine</tt>.
|
68
|
+
#
|
69
|
+
# Temperature[20, :celsius].to_celsius
|
70
|
+
# # => 20 °C
|
71
|
+
#
|
72
|
+
# Temperature[20, :celsius].to_fahrenheit
|
73
|
+
# # => 68 °F
|
74
|
+
#
|
75
|
+
# Temperature[20, :celsius].to_kelvin
|
76
|
+
# # => 293.15 K
|
77
|
+
#
|
78
|
+
# Temperature[20, :celsius].to_rankine
|
79
|
+
# # => 527.67 °R
|
80
|
+
#
|
81
|
+
# If it is necessary to convert scale dynamically, {to_scale}[rdoc-ref:Temperature#to_scale] method is
|
82
|
+
# available.
|
83
|
+
#
|
84
|
+
# Temperature[20, :celsius].to_scale(scale)
|
85
|
+
#
|
86
|
+
# All conversion formulas are taken from
|
87
|
+
# {RapidTables}[https://www.rapidtables.com/convert/temperature/index.html].
|
88
|
+
#
|
89
|
+
# Conversion precision: 2 accurate digits after the decimal dot.
|
90
|
+
#
|
91
|
+
# == Comparison
|
92
|
+
#
|
93
|
+
# Temperature implements idiomatic {<=> spaceship operator}[https://ruby-doc.org/core/Comparable.html] and
|
94
|
+
# mixes in {Comparable}[https://ruby-doc.org/core/Comparable.html] module.
|
95
|
+
#
|
96
|
+
# As a result, all methods from Comparable are available, e.g:
|
97
|
+
#
|
98
|
+
# Temperature[20, :celsius] < Temperature[25, :celsius]
|
99
|
+
# # => true
|
100
|
+
#
|
101
|
+
# Temperature[20, :celsius] <= Temperature[25, :celsius]
|
102
|
+
# # => true
|
103
|
+
#
|
104
|
+
# Temperature[20, :celsius] == Temperature[25, :celsius]
|
105
|
+
# # => false
|
106
|
+
#
|
107
|
+
# Temperature[20, :celsius] > Temperature[25, :celsius]
|
108
|
+
# # => false
|
109
|
+
#
|
110
|
+
# Temperature[20, :celsius] >= Temperature[25, :celsius]
|
111
|
+
# # => false
|
112
|
+
#
|
113
|
+
# Temperature[20, :celsius].between?(Temperature[15, :celsius], Temperature[25, :celsius])
|
114
|
+
# # => true
|
115
|
+
#
|
116
|
+
# # Starting from Ruby 2.4.6
|
117
|
+
# Temperature[20, :celsius].clamp(Temperature[20, :celsius], Temperature[25, :celsius])
|
118
|
+
# # => 20 °C
|
119
|
+
#
|
120
|
+
# Please note, if <tt>other</tt> temperature has a different scale, temperature is automatically converted
|
121
|
+
# to that scale before comparison.
|
122
|
+
#
|
123
|
+
# Temperature[20, :celsius] == Temperature[293.15, :kelvin]
|
124
|
+
# # => true
|
125
|
+
#
|
126
|
+
# IMPORTANT !!!
|
127
|
+
#
|
128
|
+
# <tt>degrees</tt> are rounded to the nearest value with a precision of 2 decimal digits before comparison.
|
129
|
+
#
|
130
|
+
# This means the following temperatures are considered as equal:
|
131
|
+
#
|
132
|
+
# Temperature[20.020, :celsius] == Temperature[20.024, :celsius]
|
133
|
+
# # => true
|
134
|
+
#
|
135
|
+
# Temperature[20.025, :celsius] == Temperature[20.029, :celsius]
|
136
|
+
# # => true
|
137
|
+
#
|
138
|
+
# while these ones are treated as NOT equal:
|
139
|
+
#
|
140
|
+
# Temperature[20.024, :celsius] == Temperature[20.029, :celsius]
|
141
|
+
# # => false
|
142
|
+
#
|
143
|
+
# == Math
|
144
|
+
#
|
145
|
+
# ==== Addition/Subtraction.
|
146
|
+
#
|
147
|
+
# Temperature[20, :celsius] + Temperature[10, :celsius]
|
148
|
+
# # => 30 °C
|
149
|
+
#
|
150
|
+
# Temperature[20, :celsius] - Temperature[10, :celsius]
|
151
|
+
# # => 10 °C
|
152
|
+
#
|
153
|
+
# If second temperature has a different scale, first temperature is automatically converted to that scale
|
154
|
+
# before <tt>degrees</tt> addition/subtraction.
|
155
|
+
#
|
156
|
+
# Temperature[283.15, :kelvin] + Temperature[10, :celsius]
|
157
|
+
# # => 10 °C
|
158
|
+
#
|
159
|
+
# Returned temperature will have the same scale as the second temperature.
|
160
|
+
#
|
161
|
+
# It is possible to add/subtract numerics.
|
162
|
+
#
|
163
|
+
# Temperature[20, :celsius] + 10
|
164
|
+
# # => 30 °C
|
165
|
+
#
|
166
|
+
# Temperature[20, :celsius] - 10
|
167
|
+
# # => 10 °C
|
168
|
+
#
|
169
|
+
# In such cases, returned temperature will have the same scale as the first temperature.
|
170
|
+
#
|
171
|
+
# Also {Ruby coersion mechanism}[https://ruby-doc.org/core/Numeric.html#method-i-coerce] is supported.
|
172
|
+
#
|
173
|
+
# 10 + Temperature[20, :celsius]
|
174
|
+
# # => 30 °C
|
175
|
+
#
|
176
|
+
# 10 - Temperature[20, :celsius]
|
177
|
+
# # => -10 °C
|
178
|
+
#
|
179
|
+
# ==== Negation
|
180
|
+
#
|
181
|
+
# -Temperature[20, :celsius]
|
182
|
+
# # => -20 °C
|
183
|
+
#
|
184
|
+
# == Queries
|
185
|
+
#
|
186
|
+
# Temperature[0, :celsius].boil_water?
|
187
|
+
# # => false
|
188
|
+
#
|
189
|
+
# Temperature[0, :celsius].freeze_water?
|
190
|
+
# # => true
|
191
|
+
#
|
192
|
+
class Temperature
|
193
|
+
include Comparable
|
194
|
+
|
195
|
+
include AdditionalHelpers
|
196
|
+
include Assertions
|
197
|
+
include Casting
|
198
|
+
include Errors
|
199
|
+
include Initialization
|
200
|
+
include Memoization
|
201
|
+
include Rounding
|
202
|
+
|
203
|
+
CELSIUS = 'celsius'
|
204
|
+
FAHRENHEIT = 'fahrenheit'
|
205
|
+
KELVIN = 'kelvin'
|
206
|
+
RANKINE = 'rankine'
|
207
|
+
|
208
|
+
# A list of all currently supported scale values.
|
209
|
+
SCALES = [CELSIUS, FAHRENHEIT, KELVIN, RANKINE].freeze
|
210
|
+
|
211
|
+
# Degrees of the temperature.
|
212
|
+
attr_reader :degrees
|
213
|
+
|
214
|
+
# Scale of the temperature. Look at {SCALES}[rdoc-ref:Temperature::SCALES] for possible values.
|
215
|
+
attr_reader :scale
|
216
|
+
|
217
|
+
##
|
218
|
+
# Creates a new instance of Temperature. Alias for <tt>new</tt>.
|
219
|
+
#
|
220
|
+
# :call-seq:
|
221
|
+
# [](degrees:, scale:)
|
222
|
+
# [](degrees, scale)
|
223
|
+
#
|
224
|
+
def self.[](*args, **kwargs)
|
225
|
+
new(*args, **kwargs)
|
226
|
+
end
|
227
|
+
|
228
|
+
##
|
229
|
+
# Creates a new instance of Temperature. Is aliased as <tt>[]</tt>.
|
230
|
+
#
|
231
|
+
# :call-seq:
|
232
|
+
# new(degrees:, scale:)
|
233
|
+
# new(degrees, scale)
|
234
|
+
#
|
235
|
+
def initialize(*positional_arguments, **keyword_arguments)
|
236
|
+
assert_either_positional_arguments_or_keyword_arguments!(positional_arguments, keyword_arguments)
|
237
|
+
|
238
|
+
if keyword_arguments.any?
|
239
|
+
initialize_via_keywords_arguments(keyword_arguments)
|
240
|
+
else # positional_arguments.any?
|
241
|
+
initialize_via_positional_arguments(positional_arguments)
|
242
|
+
end
|
243
|
+
end
|
244
|
+
|
245
|
+
# rubocop:disable Naming/AccessorMethodName
|
246
|
+
|
247
|
+
# Returns a new Temperature with updated <tt>degrees</tt>.
|
248
|
+
#
|
249
|
+
# temperature = Temperature[0, :celsius]
|
250
|
+
# # => 0 °C
|
251
|
+
#
|
252
|
+
# new_temperature = temperature.set_degrees(15)
|
253
|
+
# # => 15 °C
|
254
|
+
#
|
255
|
+
def set_degrees(degrees)
|
256
|
+
Temperature.new(degrees, scale)
|
257
|
+
end
|
258
|
+
# rubocop:enable Naming/AccessorMethodName
|
259
|
+
|
260
|
+
# rubocop:disable Naming/AccessorMethodName
|
261
|
+
|
262
|
+
# Returns a new Temperature with updated <tt>scale</tt>.
|
263
|
+
#
|
264
|
+
# temperature = Temperature[0, :celsius]
|
265
|
+
# # => 0 °C
|
266
|
+
#
|
267
|
+
# new_temperature = temperature.set_scale(:kelvin)
|
268
|
+
# # => 0 K
|
269
|
+
#
|
270
|
+
def set_scale(scale)
|
271
|
+
Temperature.new(degrees, scale)
|
272
|
+
end
|
273
|
+
# rubocop:enable Naming/AccessorMethodName
|
274
|
+
|
275
|
+
##
|
276
|
+
# Converts temperature to specific <tt>scale</tt>.
|
277
|
+
# If temperature is already in desired <tt>scale</tt>, returns current temperature object.
|
278
|
+
#
|
279
|
+
# Raises {InvalidScaleError}[rdoc-ref:Temperature::InvalidScaleError]
|
280
|
+
# when <tt>scale</tt> can not be casted to any possible scale value
|
281
|
+
# (see {SCALES}[rdoc-ref:Temperature::SCALES]).
|
282
|
+
#
|
283
|
+
# Temperature[60, :fahrenheit].to_scale(:celsius)
|
284
|
+
# # => 15.56 °C
|
285
|
+
#
|
286
|
+
def to_scale(scale)
|
287
|
+
casted_scale = cast_scale(scale)
|
288
|
+
|
289
|
+
assert_valid_scale!(casted_scale)
|
290
|
+
|
291
|
+
case casted_scale
|
292
|
+
when CELSIUS
|
293
|
+
to_celsius
|
294
|
+
when FAHRENHEIT
|
295
|
+
to_fahrenheit
|
296
|
+
when KELVIN
|
297
|
+
to_kelvin
|
298
|
+
when RANKINE
|
299
|
+
to_rankine
|
300
|
+
end
|
301
|
+
end
|
302
|
+
|
303
|
+
##
|
304
|
+
# Converts temperature to Celsius scale. If temperature is already in Celsius, returns current
|
305
|
+
# temperature object.
|
306
|
+
#
|
307
|
+
# Memoizes subsequent calls.
|
308
|
+
#
|
309
|
+
# Conversion formulas are taken from {RapidTables}[https://www.rapidtables.com/]:
|
310
|
+
# 1. {Celsius to Fahrenheit}[https://www.rapidtables.com/convert/temperature/celsius-to-fahrenheit.html].
|
311
|
+
# 2. {Celsius to Kelvin}[https://www.rapidtables.com/convert/temperature/celsius-to-kelvin.html].
|
312
|
+
# 3. {Celsius to Rankine}[https://www.rapidtables.com/convert/temperature/celsius-to-rankine.html].
|
313
|
+
#
|
314
|
+
# Temperature[0, :fahrenheit].to_celsius
|
315
|
+
# # => -17.78 °C
|
316
|
+
#
|
317
|
+
def to_celsius
|
318
|
+
memoized(:to_celsius) || memoize(:to_celsius, -> {
|
319
|
+
return self if self.scale == CELSIUS
|
320
|
+
|
321
|
+
degrees =
|
322
|
+
case self.scale
|
323
|
+
when FAHRENHEIT
|
324
|
+
(self.degrees - 32) * (5 / 9r)
|
325
|
+
when KELVIN
|
326
|
+
self.degrees - 273.15
|
327
|
+
when RANKINE
|
328
|
+
(self.degrees - 491.67) * (5 / 9r)
|
329
|
+
end
|
330
|
+
|
331
|
+
Temperature.new(degrees, CELSIUS)
|
332
|
+
})
|
333
|
+
end
|
334
|
+
|
335
|
+
##
|
336
|
+
# Converts temperature to Fahrenheit scale. If temperature is already in Fahrenheit, returns current
|
337
|
+
# temperature object.
|
338
|
+
#
|
339
|
+
# Memoizes subsequent calls.
|
340
|
+
#
|
341
|
+
# Conversion formulas are taken from {RapidTables}[https://www.rapidtables.com/]:
|
342
|
+
# 1. {Fahrenheit to Celsius}[https://www.rapidtables.com/convert/temperature/fahrenheit-to-celsius.html].
|
343
|
+
# 2. {Fahrenheit to Kelvin}[https://www.rapidtables.com/convert/temperature/fahrenheit-to-kelvin.html].
|
344
|
+
# 3. {Fahrenheit to Rankine}[https://www.rapidtables.com/convert/temperature/fahrenheit-to-rankine.html].
|
345
|
+
#
|
346
|
+
# Temperature[0, :celsius].to_fahrenheit
|
347
|
+
# # => 32 °F
|
348
|
+
#
|
349
|
+
def to_fahrenheit
|
350
|
+
memoized(:to_fahrenheit) || memoize(:to_fahrenheit, -> {
|
351
|
+
return self if self.scale == FAHRENHEIT
|
352
|
+
|
353
|
+
degrees =
|
354
|
+
case self.scale
|
355
|
+
when CELSIUS
|
356
|
+
self.degrees * (9 / 5r) + 32
|
357
|
+
when KELVIN
|
358
|
+
self.degrees * (9 / 5r) - 459.67
|
359
|
+
when RANKINE
|
360
|
+
self.degrees - 459.67
|
361
|
+
end
|
362
|
+
|
363
|
+
Temperature.new(degrees, FAHRENHEIT)
|
364
|
+
})
|
365
|
+
end
|
366
|
+
|
367
|
+
##
|
368
|
+
# Converts temperature to Kelvin scale. If temperature is already in Kelvin, returns current
|
369
|
+
# temperature object.
|
370
|
+
#
|
371
|
+
# Memoizes subsequent calls.
|
372
|
+
#
|
373
|
+
# Conversion formulas are taken from {RapidTables}[https://www.rapidtables.com/]:
|
374
|
+
# 1. {Kelvin to Celsius}[https://www.rapidtables.com/convert/temperature/kelvin-to-celsius.html].
|
375
|
+
# 2. {Kelvin to Fahrenheit}[https://www.rapidtables.com/convert/temperature/kelvin-to-fahrenheit.html].
|
376
|
+
# 3. {Kelvin to Rankine}[https://www.rapidtables.com/convert/temperature/kelvin-to-rankine.html].
|
377
|
+
#
|
378
|
+
# Temperature[0, :kelvin].to_rankine
|
379
|
+
# # => 0 °R
|
380
|
+
#
|
381
|
+
def to_kelvin
|
382
|
+
memoized(:to_kelvin) || memoize(:to_kelvin, -> {
|
383
|
+
return self if self.scale == KELVIN
|
384
|
+
|
385
|
+
degrees =
|
386
|
+
case self.scale
|
387
|
+
when CELSIUS
|
388
|
+
self.degrees + 273.15
|
389
|
+
when FAHRENHEIT
|
390
|
+
(self.degrees + 459.67) * (5 / 9r)
|
391
|
+
when RANKINE
|
392
|
+
self.degrees * (5 / 9r)
|
393
|
+
end
|
394
|
+
|
395
|
+
Temperature.new(degrees, KELVIN)
|
396
|
+
})
|
397
|
+
end
|
398
|
+
|
399
|
+
##
|
400
|
+
# Converts temperature to Rankine scale. If temperature is already in Rankine, returns current
|
401
|
+
# temperature object.
|
402
|
+
#
|
403
|
+
# Memoizes subsequent calls.
|
404
|
+
#
|
405
|
+
# Conversion formulas are taken from {RapidTables}[https://www.rapidtables.com/]:
|
406
|
+
# 1. {Rankine to Celsius}[https://www.rapidtables.com/convert/temperature/rankine-to-celsius.html].
|
407
|
+
# 2. {Rankine to Fahrenheit}[https://www.rapidtables.com/convert/temperature/rankine-to-fahrenheit.html].
|
408
|
+
# 3. {Rankine to Kelvin}[https://www.rapidtables.com/convert/temperature/rankine-to-kelvin.html].
|
409
|
+
#
|
410
|
+
# Temperature[0, :rankine].to_kelvin
|
411
|
+
# # => 0 K
|
412
|
+
#
|
413
|
+
def to_rankine
|
414
|
+
memoized(:to_rankine) || memoize(:to_rankine, -> {
|
415
|
+
return self if self.scale == RANKINE
|
416
|
+
|
417
|
+
degrees =
|
418
|
+
case self.scale
|
419
|
+
when CELSIUS
|
420
|
+
(self.degrees + 273.15) * (9 / 5r)
|
421
|
+
when FAHRENHEIT
|
422
|
+
self.degrees + 459.67
|
423
|
+
when KELVIN
|
424
|
+
self.degrees * (9 / 5r)
|
425
|
+
end
|
426
|
+
|
427
|
+
Temperature.new(degrees, RANKINE)
|
428
|
+
})
|
429
|
+
end
|
430
|
+
|
431
|
+
##
|
432
|
+
# Compares temperture with <tt>other</tt> temperature.
|
433
|
+
#
|
434
|
+
# Returns <tt>0</tt> if they are considered as equal.
|
435
|
+
#
|
436
|
+
# Two temperatures are considered as equal when they have the same amount of <tt>degrees</tt>.
|
437
|
+
#
|
438
|
+
# Returns <tt>-1</tt> if temperature is lower than <tt>other</tt> temperature.
|
439
|
+
#
|
440
|
+
# Returns <tt>1</tt> if temperature is higher than <tt>other</tt> temperature.
|
441
|
+
#
|
442
|
+
# If <tt>other</tt> temperature has a different scale, temperature is automatically converted to that
|
443
|
+
# scale before <tt>degrees</tt> comparison.
|
444
|
+
#
|
445
|
+
# Temperature[20, :celsius] <=> Temperature[20, :celsius]
|
446
|
+
# # => 0
|
447
|
+
#
|
448
|
+
# Temperature[20, :celsius] <=> Temperature[293.15, :kelvin]
|
449
|
+
# # => 0
|
450
|
+
#
|
451
|
+
# IMPORTANT!!!
|
452
|
+
#
|
453
|
+
# This method rounds <tt>degrees</tt> to the nearest value with a precision of 2 decimal digits.
|
454
|
+
#
|
455
|
+
# This means the following:
|
456
|
+
#
|
457
|
+
# Temperature[20.020, :celsius] <=> Temperature[20.024, :celsius]
|
458
|
+
# # => 0
|
459
|
+
#
|
460
|
+
# Temperature[20.025, :celsius] <=> Temperature[20.029, :celsius]
|
461
|
+
# # => 0
|
462
|
+
#
|
463
|
+
# Temperature[20.024, :celsius] <=> Temperature[20.029, :celsius]
|
464
|
+
# # => -1
|
465
|
+
#
|
466
|
+
def <=>(other)
|
467
|
+
return unless assert_temperature(other)
|
468
|
+
|
469
|
+
round_degrees(self.to_scale(other.scale).degrees) <=> round_degrees(other.degrees)
|
470
|
+
end
|
471
|
+
|
472
|
+
##
|
473
|
+
# Returns true when temperature boils water (is greater than or equal to 100 °C),
|
474
|
+
# false otherwise.
|
475
|
+
#
|
476
|
+
def boil_water?
|
477
|
+
self.to_celsius.degrees >= 100
|
478
|
+
end
|
479
|
+
|
480
|
+
##
|
481
|
+
# Returns true when temperature freezes water (is less than or equal to 0 °C),
|
482
|
+
# false otherwise.
|
483
|
+
#
|
484
|
+
def freeze_water?
|
485
|
+
self.to_celsius.degrees <= 0
|
486
|
+
end
|
487
|
+
|
488
|
+
# Is used by {+}[rdoc-ref:Temperature#+] and {-}[rdoc-ref:Temperature#-]
|
489
|
+
# for {Ruby coersion mechanism}[https://ruby-doc.org/core/Numeric.html#method-i-coerce].
|
490
|
+
def coerce(numeric) #:nodoc:
|
491
|
+
assert_numeric!(numeric)
|
492
|
+
|
493
|
+
[Temperature.new(numeric, self.scale), self]
|
494
|
+
end
|
495
|
+
|
496
|
+
# Returns a string containing a human-readable representation of temperature.
|
497
|
+
def inspect #:nodoc:
|
498
|
+
rounded_degrees = round_degrees(degrees)
|
499
|
+
|
500
|
+
printable_degrees = degrees_without_decimal?(rounded_degrees) ? rounded_degrees.to_i : rounded_degrees
|
501
|
+
|
502
|
+
scale_symbol =
|
503
|
+
case self.scale
|
504
|
+
when CELSIUS
|
505
|
+
'°C'
|
506
|
+
when FAHRENHEIT
|
507
|
+
'°F'
|
508
|
+
when KELVIN
|
509
|
+
'K'
|
510
|
+
when RANKINE
|
511
|
+
'°R'
|
512
|
+
end
|
513
|
+
|
514
|
+
"#{printable_degrees} #{scale_symbol}"
|
515
|
+
end
|
516
|
+
end
|
517
|
+
# rubocop:enable Metrics/ClassLength
|
518
|
+
end
|