Temperature is a simple Value Object for basic temperature operations like conversions from Celsius to Fahrenhait or Kelvin etc.
Supported scales: Celsius , Fahrenheit , Kelvin and Rankine .
Creating Temperatures
A new temperature can be created in multiple ways:
-
Using keyword arguments:
Temperature.new(degrees: 0, scale: :celsius)
-
Using positional arguments:
Temperature.new(0, :celsius)
-
Even more concise way using Temperature.[] (an alias of Temperature.new ):
Temperature[0, :celsius]
Creating Temperatures from already existing temperature objects
Sometimes it is useful to create a new temperature from already existing one.
For such cases, there are set_degrees}[rdoc-ref:BasicTemperature#set_degrees and {set_scale.
Since temperatures are Value Objects, both methods returns new instances.
Examples:
temperature = Temperature[0, :celsius]
# => 0 °C
new_temperature = temperature.set_degrees(15)
# => 15 °C
temperature = Temperature[0, :celsius]
# => 0 °C
new_temperature = temperature.set_scale(:kelvin)
# => 0 K
Conversions
Temperatures can be converted to diffirent scales.
Currently, the following scales are supported: Celsius , Fahrenheit , Kelvin and Rankine .
Temperature[20, :celsius].to_celsius
# => 20 °C
Temperature[20, :celsius].to_fahrenheit
# => 68 °F
Temperature[20, :celsius].to_kelvin
# => 293.15 K
Temperature[20, :celsius].to_rankine
# => 527.67 °R
If it is necessary to convert scale dynamically, to_scale method is available.
Temperature[20, :celsius].to_scale(scale)
All conversion formulas are taken from RapidTables.
Conversion precision: 2 accurate digits after the decimal dot.
Comparison
Temperature implements idiomatic <=> spaceship operator and mixes in Comparable module.
As a result, all methods from Comparable are available, e.g:
Temperature[20, :celsius] < Temperature[25, :celsius]
# => true
Temperature[20, :celsius] <= Temperature[25, :celsius]
# => true
Temperature[20, :celsius] == Temperature[25, :celsius]
# => false
Temperature[20, :celsius] > Temperature[25, :celsius]
# => false
Temperature[20, :celsius] >= Temperature[25, :celsius]
# => false
Temperature[20, :celsius].between?(Temperature[15, :celsius], Temperature[25, :celsius])
# => true
# Starting from Ruby 2.4.6
Temperature[20, :celsius].clamp(Temperature[20, :celsius], Temperature[25, :celsius])
# => 20 °C
Please note, if other temperature has a different scale, temperature is automatically converted to that scale before comparison.
Temperature[20, :celsius] == Temperature[293.15, :kelvin]
# => true
IMPORTANT !!!
degrees are rounded to the nearest value with a precision of 2 decimal digits before comparison.
This means the following temperatures are considered as equal:
Temperature[20.020, :celsius] == Temperature[20.024, :celsius]
# => true
Temperature[20.025, :celsius] == Temperature[20.029, :celsius]
# => true
while these ones are treated as NOT equal:
Temperature[20.024, :celsius] == Temperature[20.029, :celsius]
# => false
Math
Addition/Subtraction.
Temperature[20, :celsius] + Temperature[10, :celsius]
# => 30 °C
Temperature[20, :celsius] - Temperature[10, :celsius]
# => 10 °C
If second temperature has a different scale, first temperature is automatically converted to that scale before degrees addition/subtraction.
Temperature[283.15, :kelvin] + Temperature[10, :celsius]
# => 10 °C
Returned temperature will have the same scale as the second temperature.
It is possible to add/subtract numerics.
Temperature[20, :celsius] + 10
# => 30 °C
Temperature[20, :celsius] - 10
# => 10 °C
In such cases, returned temperature will have the same scale as the first temperature.
Also Ruby coersion mechanism is supported.
10 + Temperature[20, :celsius]
# => 30 °C
10 - Temperature[20, :celsius]
# => -10 °C
Negation
-Temperature[20, :celsius]
# => -20 °C
|