我正试图在TestFirst.org上解决Ruby中的温度问题。我的目标是编写代码以使用test,如下所示。这是测试规范:
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
我将测试传递给它要求我使用Factory方法来定义类方法from_celsius
和from_fahrenheit
,它们给出了这个错误:“NoMethodERror:undefined method”in_celsius“”< / p>
在from_celsius
和from_fahrenheit
下,我考虑创建变量@temp1
和@temp2
,然后使用它来根据in_fahrenheit
和{计算温度{1}}但我需要确定变量是否不是符号。这也不起作用。
答案 0 :(得分:3)
问题是from_celsius
和from_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