basic_temperature 0.2.2 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|