Ruby Class: Temperature Conversion

TemperatureConverter: A Ruby class for converting between the Celcius, Fahrenheit, Kelvin and Rankine temperature scales.

Usage:

RUBY:
  1. tc = TemperatureConverter.new()
  2. degF = tc.convert( 40, "C", "F" )
  3. # => 104.0

See the unit test code at the bottom of the class for more details.

RUBY:
  1. =begin rdoc
  2.   Converts a numeric temperature value from one temperature scale to another.
  3.  
  4.   By Chris Cummer, 2006
  5.   version 1.0
  6. =end
  7. class TemperatureConverter
  8.   attr_accessor :supportedScales
  9.  
  10.   @@kelvinCDiff = 273.15
  11.   @@fahrCDiff = 32
  12.   @@fahrMultiplier = 0.56
  13.   @@celMultiplier = 1.80
  14.   @@rankDiff = 459.67
  15.  
  16.  
  17.   # ------------------------------ Initialization ------------------------------ #
  18.  
  19.  
  20. =begin rdoc
  21.   Initialize the instance and define the supported temperature scales
  22. =end
  23. def initialize()
  24.     @supportedScales = Array[ "C", "F", "K", "R" ]
  25.   end
  26.  
  27.  
  28.   # ------------------------------ Public Methods ------------------------------ #
  29.  
  30.  
  31. =begin rdoc
  32.   Takes a numeric value and two string identifiers for the scales and converts between the scales for the provided value
  33. =end 
  34.   def convert( pVal = 0, pFrom = '', pTo = '' )
  35.     theMethod = pFrom.downcase + "2" + pTo.downcase
  36.    
  37.     if ( pVal.respond_to? :to_f )
  38.       eval "return self." <<theMethod <<"( pVal.to_f() )"
  39.     else
  40.       raise "Supplied input value is not numeric: " <<pVal
  41.     end
  42.   end
  43.  
  44. =begin rdoc
  45.   Fahrenheit to Celcius
  46. =end
  47. def f2c( pVal )
  48.     return ( pVal - @@fahrCDiff ) * @@fahrMultiplier
  49.   end
  50.  
  51. =begin rdoc
  52.   Celcius to Fahrenheit
  53. =end
  54. def c2f( pVal )
  55.     return ( pVal * @@celMultiplier ) + @@fahrCDiff
  56.   end
  57.  
  58. =begin rdoc
  59.   Fahrenheit to Kelvin
  60. =end 
  61.   def f2k( pVal )
  62.     return self.f2c( pVal ) + @@kelvinCDiff
  63.   end
  64.  
  65. =begin rdoc
  66.   Celcius to Kelvin
  67. =end 
  68.   def c2k( pVal )
  69.     return pVal + @@kelvinCDiff
  70.   end
  71.  
  72. =begin rdoc
  73.   Kelvin to Fahrenheit
  74. =end 
  75.   def k2f( pVal )
  76.     return self.c2f( self.k2c( pVal ) )
  77.   end
  78.  
  79. =begin rdoc
  80.   Kelvin to Celcius
  81. =end 
  82.   def k2c( pVal )
  83.     return pVal - @@kelvinCDiff
  84.   end
  85.  
  86. =begin rdoc
  87.   Fahrenheit to Rankine
  88. =end 
  89.   def f2r( pVal )
  90.     return pVal + @@rankDiff
  91.   end
  92.  
  93. =begin rdoc
  94.   Celcius to Rankine
  95. =end 
  96.   def c2r( pVal )
  97.     return pVal * @@celMultiplier + @@fahrCDiff + @@rankDiff
  98.   end
  99.  
  100. =begin rdoc
  101.   Kelvin to Rankine
  102. =end 
  103.   def k2r( pVal )
  104.     return pVal * @@celMultiplier
  105.   end
  106.  
  107. =begin rdoc
  108.   Rankine to Fahrenheit
  109. =end 
  110.   def r2f( pVal )
  111.     return pVal - @@rankDiff
  112.   end
  113.  
  114. =begin rdoc
  115.   Rankine to Celius
  116. =end 
  117.   def r2c( pVal )
  118.     return ( pVal - @@fahrCDiff - @@rankDiff ) / @@celMultiplier
  119.   end
  120.  
  121. =begin rdoc
  122.   Rankine to Kelvin
  123. =end 
  124.   def r2k( pVal )
  125.     return pVal / @@celMultiplier
  126.   end
  127.  
  128.  
  129. =begin rdoc
  130.   If the temperature scale parameters don't match any supported temperature scales this error is thrown
  131. =end
  132. def method_missing( m, *args )
  133.     raise "Public method does not exist with this signature: " <<m.to_s() <<"()"
  134.   end
  135. end
  136.  
  137.  
  138. # ------------------------------ Unit Testing ------------------------------ #
  139.  
  140.  
  141. if __FILE__ == $0
  142.   # Ask the user for the input temperature (default to 0 if nothing is entered)
  143.   STDOUT.flush
  144.   theTemp = gets.chomp()
  145.   theTemp != "" ? theTemp = theTemp : theTemp = 0.to_s()
  146.  
  147.   tc = TemperatureConverter.new()
  148.  
  149.   # Takes an array of temperature short-hands and runs through every combination of them (excluding same sets)
  150.   tc.supportedScales.each do |scaleA|
  151.     tc.supportedScales.each do |scaleB|
  152.       if ( scaleA != scaleB )
  153.         theResult = tc.convert( theTemp, scaleA, scaleB )
  154.        
  155.         if ( theResult.is_a? String )
  156.           puts theResult.to_s()
  157.         else
  158.           puts format( "%.2f", theTemp.to_f() ) <<"˚" <<scaleA <<" = " <<format( "%.2f", theResult.to_f() ) <<"˚" + scaleB
  159.         end
  160.       end
  161.     end
  162.   end
  163. end