TestFirst.org 红宝石的温度等级



我正在尝试解决 Ruby 在 TestFirst.org 中的温度问题。我的目标是编写代码以使用测试,如下所示。以下是测试规范:

require "10_temperature_object"
describe Temperature do
  describe "can be constructed with an options hash" do
    describe "in degrees fahrenheit" do
      it "at 50 degrees" do
        Temperature.new(:f => 50).in_fahrenheit.should == 50
      end
      describe "and correctly convert to celsius" do
        it "at freezing" do
          Temperature.new(:f => 32).in_celsius.should == 0
        end
        it "at boiling" do
          Temperature.new(:f => 212).in_celsius.should == 100
        end
        it "at body temperature" do
          Temperature.new(:f => 98.6).in_celsius.should == 37
        end
        it "at an arbitrary temperature" do
          Temperature.new(:f => 68).in_celsius.should == 20
        end
      end
    end
    describe "in degrees celsius" do
      it "at 50 degrees" do
        Temperature.new(:c => 50).in_celsius.should == 50
      end
      describe "and correctly convert to fahrenheit" do
        it "at freezing" do
          Temperature.new(:c => 0).in_fahrenheit.should == 32
        end
        it "at boiling" do
          Temperature.new(:c => 100).in_fahrenheit.should == 212
        end
        it "at body temperature" do
          Temperature.new(:c => 37).in_fahrenheit.should be_within(0.1).of(98.6)
          # Why do we need to use be_within here?
          # See http://www.ruby-forum.com/topic/169330
          # and http://groups.google.com/group/rspec/browse_thread/thread/f3ebbe3c313202bb
          # Also, try "puts 0.5 - 0.4 - 0.1" -- pretty crazy, right?
        end
      end
    end
  end
  # Factory Method is a design pattern, not a Ruby language feature.
  # One way to implement this pattern in Ruby is via class methods --
  # that is, methods defined on the class (Temperature) rather than
  # on individual instances of the class.
  describe "can be constructed via factory methods" do
    it "in degrees celsius" do
      Temperature.from_celsius(50).in_celsius.should == 50
      Temperature.from_celsius(50).in_fahrenheit.should == 122
    end
    it "in degrees fahrenheit" do
      Temperature.from_fahrenheit(50).in_fahrenheit.should == 50
      Temperature.from_fahrenheit(50).in_celsius.should == 10
    end
  end
  # test-driving bonus:
  #
  # 1. make two class methods -- ftoc and ctof
  # 2. refactor to call those methods from the rest of the object
  #
  # run *all* the tests during your refactoring, to make sure you did it right
  #
  describe "utility class methods" do
  end
  # Here's another way to solve the problem!
  describe "Temperature subclasses" do
    describe "Celsius subclass" do
      it "is constructed in degrees celsius" do
        Celsius.new(50).in_celsius.should == 50
        Celsius.new(50).in_fahrenheit.should == 122
      end
      it "is a Temperature subclass" do
        Celsius.new(0).should be_a(Temperature)
      end
    end
    describe "Fahrenheit subclass" do
      it "is constructed in degrees fahrenheit" do
        Fahrenheit.new(50).in_fahrenheit.should == 50
        Fahrenheit.new(50).in_celsius.should == 10
      end
      it "is a Temperature subclass" do
        Fahrenheit.new(0).should be_a(Temperature)
      end
    end
  end
end

这是我的代码:

class Temperature
    #initialize of temperature class
    def initialize(hash = {})   #option hash parameter
        @hash = hash    #accepts either :f or :c
    end
    def self.from_celsius(temp)
        @temp1 = temp
    end
    def self.from_fahrenheit(temp)
        @temp2 = temp
    end
    def in_fahrenheit
        if @hash.has_key?(:f)
            return @hash[:f]    #return value of @hash[:f]
        elsif @hash.has_key?(:c)
            return @hash[:c]*9.to_f/5+32    #formula to convert from C to F
        elsif @temp1.is_a? Numeric
            return @temp1*9.to_f/5+32
        else
            return @temp1
        end
    end
    def in_celsius
        if @hash.has_key?(:c)
            return @hash[:c]    #return value of @hash[:c]
        elsif @hash.has_key?(:f)
            return (@hash[:f]-32)*5.to_f/9  #formula to convert from F to C
        elsif @temp2.is_a? Numeric
            return (@temp2-32)*5.to_f/9
        else
            return @temp1
        end
    end
end

通过了测试,直到它要求我使用工厂方法来定义类方法from_celsiusfrom_fahrenheit,这给出了这个错误:"NoMethodERror:未定义的方法"in_celsius"

from_celsiusfrom_fahrenheit下,我正在考虑创建@temp1@temp2变量,然后使用它来根据in_fahrenheitin_celsius计算温度,但我需要确定变量是否不是符号。那也没用。

问题from_celsiusfrom_fahrenheit方法返回一个Fixnum(因为您在测试中传递了一个数字作为参数)。 Fixnum没有这些方法。

让我们以这个例子为例:

Temperature.from_celsius(50).in_celsius.should == 50

Temperature.from_celsius(50)将返回值 50。然后 ruby 将尝试为 50 对象调用 in_celsius

50.in_celsius.should == 50

它会失败。此外,您在类方法中定义实例变量(@temp1 和 @temp2),这不起作用。您可以使用这些类方法来创建Temperature的实例?

def self.from_celsius(temp)
    Temperature.new({c: temp})
end
def self.from_fahrenheit(temp)
    Temperature.new({f: temp})
end

相关内容

最新更新