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 ofTemperature.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 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
Queries
Temperature[0, :celsius].boil_water?
# => false
Temperature[0, :celsius].freeze_water?
# => true
- MODULE BasicTemperature::Temperature::AdditionalHelpers
- MODULE BasicTemperature::Temperature::Assertions
- MODULE BasicTemperature::Temperature::Casting
- MODULE BasicTemperature::Temperature::Errors
- MODULE BasicTemperature::Temperature::Initialization
- MODULE BasicTemperature::Temperature::Memoization
- MODULE BasicTemperature::Temperature::Rounding
- #
- B
- F
- N
- S
- T
- Comparable
- BasicTemperature::Temperature::AdditionalHelpers
- BasicTemperature::Temperature::Assertions
- BasicTemperature::Temperature::Casting
- BasicTemperature::Temperature::Errors
- BasicTemperature::Temperature::Initialization
- BasicTemperature::Temperature::Memoization
- BasicTemperature::Temperature::Rounding
CELSIUS | = | 'celsius' |
FAHRENHEIT | = | 'fahrenheit' |
KELVIN | = | 'kelvin' |
RANKINE | = | 'rankine' |
SCALES | = | [CELSIUS, FAHRENHEIT, KELVIN, RANKINE].freeze |
A list of all currently supported scale values. |
[R] | degrees | Degrees of the temperature. |
[R] | scale | Scale of the temperature. Look at SCALES for possible values. |
[](degrees, scale) Link
Creates a new instance of Temperature
. Alias for new
.
Source: show
# File lib/basic_temperature/temperature.rb, line 224 def self.[](*args, **kwargs) new(*args, **kwargs) end
new(degrees, scale) Link
Creates a new instance of Temperature
. Is aliased as []
.
Source: show
# File lib/basic_temperature/temperature.rb, line 235 def initialize(*positional_arguments, **keyword_arguments) assert_either_positional_arguments_or_keyword_arguments!(positional_arguments, keyword_arguments) if keyword_arguments.any? initialize_via_keywords_arguments(keyword_arguments) else # positional_arguments.any? initialize_via_positional_arguments(positional_arguments) end end
Compares temperture with other
temperature.
Returns 0
if they are considered as equal.
Two temperatures are considered as equal when they have the same amount of degrees
.
Returns -1
if temperature is lower than other
temperature.
Returns 1
if temperature is higher than other
temperature.
If other
temperature has a different scale, temperature is automatically converted to that scale before degrees
comparison.
Temperature[20, :celsius] <=> Temperature[20, :celsius]
# => 0
Temperature[20, :celsius] <=> Temperature[293.15, :kelvin]
# => 0
IMPORTANT!!!
This method rounds degrees
to the nearest value with a precision of 2 decimal digits.
This means the following:
Temperature[20.020, :celsius] <=> Temperature[20.024, :celsius]
# => 0
Temperature[20.025, :celsius] <=> Temperature[20.029, :celsius]
# => 0
Temperature[20.024, :celsius] <=> Temperature[20.029, :celsius]
# => -1
Source: show
# File lib/basic_temperature/temperature.rb, line 466 def <=>(other) return unless assert_temperature(other) round_degrees(self.to_scale(other.scale).degrees) <=> round_degrees(other.degrees) end
Returns true when temperature boils water (is greater than or equal to 100 °C), false otherwise.
Source: show
# File lib/basic_temperature/temperature.rb, line 476 def boil_water? self.to_celsius.degrees >= 100 end
Returns true when temperature freezes water (is less than or equal to 0 °C), false otherwise.
Source: show
# File lib/basic_temperature/temperature.rb, line 484 def freeze_water? self.to_celsius.degrees <= 0 end
Returns a new Temperature
with updated degrees
.
temperature = Temperature[0, :celsius]
# => 0 °C
new_temperature = temperature.set_degrees(15)
# => 15 °C
Source: show
# File lib/basic_temperature/temperature.rb, line 255 def set_degrees(degrees) Temperature.new(degrees, scale) end
Returns a new Temperature
with updated scale
.
temperature = Temperature[0, :celsius]
# => 0 °C
new_temperature = temperature.set_scale(:kelvin)
# => 0 K
Source: show
# File lib/basic_temperature/temperature.rb, line 270 def set_scale(scale) Temperature.new(degrees, scale) end
Converts temperature to Celsius scale. If temperature is already in Celsius, returns current temperature object.
Memoizes subsequent calls.
Conversion formulas are taken from RapidTables:
Temperature[0, :fahrenheit].to_celsius
# => -17.78 °C
Source: show
# File lib/basic_temperature/temperature.rb, line 317 def to_celsius memoized(:to_celsius) || memoize(:to_celsius, -> { return self if self.scale == CELSIUS degrees = case self.scale when FAHRENHEIT (self.degrees - 32) * (5 / 9r) when KELVIN self.degrees - 273.15 when RANKINE (self.degrees - 491.67) * (5 / 9r) end Temperature.new(degrees, CELSIUS) }) end
Converts temperature to Fahrenheit scale. If temperature is already in Fahrenheit, returns current temperature object.
Memoizes subsequent calls.
Conversion formulas are taken from RapidTables:
Temperature[0, :celsius].to_fahrenheit
# => 32 °F
Source: show
# File lib/basic_temperature/temperature.rb, line 349 def to_fahrenheit memoized(:to_fahrenheit) || memoize(:to_fahrenheit, -> { return self if self.scale == FAHRENHEIT degrees = case self.scale when CELSIUS self.degrees * (9 / 5r) + 32 when KELVIN self.degrees * (9 / 5r) - 459.67 when RANKINE self.degrees - 459.67 end Temperature.new(degrees, FAHRENHEIT) }) end
Converts temperature to Kelvin scale. If temperature is already in Kelvin, returns current
temperature object.
Memoizes subsequent calls.
Conversion formulas are taken from RapidTables:
Temperature[0, :kelvin].to_rankine
# => 0 °R
Source: show
# File lib/basic_temperature/temperature.rb, line 381 def to_kelvin memoized(:to_kelvin) || memoize(:to_kelvin, -> { return self if self.scale == KELVIN degrees = case self.scale when CELSIUS self.degrees + 273.15 when FAHRENHEIT (self.degrees + 459.67) * (5 / 9r) when RANKINE self.degrees * (5 / 9r) end Temperature.new(degrees, KELVIN) }) end
Converts temperature to Rankine scale. If temperature is already in Rankine, returns current temperature object.
Memoizes subsequent calls.
Conversion formulas are taken from RapidTables:
Temperature[0, :rankine].to_kelvin
# => 0 K
Source: show
# File lib/basic_temperature/temperature.rb, line 413 def to_rankine memoized(:to_rankine) || memoize(:to_rankine, -> { return self if self.scale == RANKINE degrees = case self.scale when CELSIUS (self.degrees + 273.15) * (9 / 5r) when FAHRENHEIT self.degrees + 459.67 when KELVIN self.degrees * (9 / 5r) end Temperature.new(degrees, RANKINE) }) end
Converts temperature to specific scale
. If temperature is already in desired scale
, returns current temperature object.
Raises InvalidScaleError when scale
can not be casted to any possible scale value (see SCALES).
Temperature[60, :fahrenheit].to_scale(:celsius)
# => 15.56 °C
Source: show
# File lib/basic_temperature/temperature.rb, line 286 def to_scale(scale) casted_scale = cast_scale(scale) assert_valid_scale!(casted_scale) case casted_scale when CELSIUS to_celsius when FAHRENHEIT to_fahrenheit when KELVIN to_kelvin when RANKINE to_rankine end end