Basic Temperature
basic_temperature
is a Ruby library which provides a simple value object to work with temperatures and
allows to perform basic operations like conversion from Celsius to Kelvin, from Kelvin to Fahrenheit etc.
Features
-
Provides a
Temperature
class which encapsulates all information about a certain temperature, such as its amount of degrees and its scale. -
Provides APIs for exchanging temperatures from one scale to another (currently Celsius, Fahrenheit, Kelvin and Rankine).
-
Allows comparing temperatures between each other.
-
Queries like
boil_water?
,freeze_water?
. -
Tested against Ruby 2.3, 2.4, 2.5, 2.6, 2.7, 3.0 and 3.1. See .github/workflows/ci.yml.
Dependencies
- None.
Documentation
- Visit https://marian13.github.io/basic_temperature/ to view the documentation.
Installation
Gemfile:
gem 'basic_temperature', '~> 1.0.0'
And then run:
$ bundle install
And that's it.
You can access all the features of basic_temperature
by creating instances of BasicTemperature::Temperature
.
But there is a shorter form.
If Temperature
constant was not used before in your app, you can add this line to your Gemfile:
gem 'basic_temperature', '~> 1.0.0', require: ['basic_temperature/alias']
This way BasicTemperature::Temperature
class will be accesible simply by Temperature
.
The following guide assumes you have chosen the shorter form.
If not, just replace all Temperature
to BasicTemperature::Temperature
.
Usage
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 an already existing one.
For such cases, there are set_degrees
and set_scale
.
Since temperatures are value objects, both methods return 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 different 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 the second temperature has a different scale, the first 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
Queries
Temperature[0, :celsius].boil_water?
# => false
Temperature[0, :celsius].freeze_water?
# => true
Versioning
Basic Temperature follows the Semantic Versioning standard.
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/marian13/basic_temperature.
Development
Local Machine
-
Check specs:
bundle exec rspec
-
Check linter:
bundle exec rubocop
-
Update docs:
bundle exec sdoc lib -T rails -o docs --github
-
Find missed docs:
bundle exec inch
-
Check for vulnerable gem versions, insecure gem sources, etc...
bundle exec bundle-audit check --update
Docker
-
Build container:
docker build . -f docker/3.1/Dockerfile -t basic_temperature:3.1
-
Run specs inside the container:
docker run --rm -it basic_temperature:3.1 bundle exec rspec
-
Interactive Bash shell:
docker run --rm -it basic_temperature:3.1 bash
-
Run container with volume (share gem folder between host and container):
docker run --rm -it -v $(pwd):/gem basic_temperature:3.1 bash
-
Ruby REPL with already required gem files:
docker run --rm -it basic_temperature:3.1 bin/console
-
3.1
can be replaced by2.3
,2.4
,2.5
,2.6
,2.7
, and3.0
.
License
The gem is available as open-source under the terms of the MIT License.
Copyright (c) 2022 Marian Kostyk.