module TempConvert

  FROM_TEMP_SCALE_TO_K = 
  {'kelvin'     => lambda{|t| t},
   'celsius'    => lambda{|t| t + 273.15},
   'fahrenheit' => lambda{|t| (t + 459.67) * 5/9.0},
   'rankine'    => lambda{|t| t * 5/9.0},
   'delisle'    => lambda{|t| 373.15 - t * 2/3.0},
   'newton'     => lambda{|t| t * 100/33.0 + 273.15},
   'reaumur'    => lambda{|t| t * 5/4.0 + 273.15},
   'roemer'     => lambda{|t| (t - 7.5) * 40/21.0 + 273.15}}

  TO_TEMP_SCALE_FROM_K = 
  {'kelvin'     => lambda{|t| t},
   'celsius'    => lambda{|t| t - 273.15},
   'fahrenheit' => lambda{|t| t * 9/5.0 - 459.67},
   'rankine'    => lambda{|t| t * 9/5.0},
   'delisle'    => lambda{|t| (373.15 - t) * 3/2.0},
   'newton'     => lambda{|t| (t - 273.15) * 33/100.0},
   'reaumur'    => lambda{|t| (t - 273.15) * 4/5.0},
   'roemer'     => lambda{|t| (t - 273.15) * 21/40.0 + 7.5}}

  SUPPORTED_SCALES = FROM_TEMP_SCALE_TO_K.keys.join('|')

  def self.method_missing(meth, *args, &block)
    if valid_temperature_conversion?(meth) then
      convert_temperature(meth, *args)
    else
      super
    end
  end

  def self.respond_to_missing?(meth, include_private = false)
    valid_temperature_conversion?(meth) || super
  end

  def self.valid_temperature_conversion?(meth)
   !!(meth.to_s =~ /(
  end

  def self.convert_temperature(meth, temp)
    from_scale, to_scale = meth.to_s.split()
    return temp.to_f if from_scale == to_scale 
    TO_TEMP_SCALE_FROM_K[to_scale].call(FROM_TEMP_SCALE_TO_K[from_scale].call(temp)).round(2)
  end

end