Reputation: 479
I'm working on a TestFirst exercise (temperature_object) and have come to a standstill when it comes to integrating a subclass. So far I've got:
class Temperature
def initialize(opts = {})
@options = opts
@c = @options[:c]
@f = @options[:f]
end
def self.from_celsius(num)
self.new(:c => num)
end
def self.from_fahrenheit(num)
self.new(:f => num)
end
def in_celsius
if @options.has_key?(:c)
@c
elsif @options.has_key?(:f)
ctof(@f)
end
end
def in_fahrenheit
if @options.has_key?(:f)
@f
elsif @options.has_key?(:c)
ftoc(@c)
end
end
def ftoc(num)
(((num * 9) / 5.000) + 32)
end
def ctof(num)
(((num - 32) * 5) / 9.0000)
end
end
class Celsius < Temperature
def initialize(num)
@c = num
end
end
class Fahrenheit < Temperature
def initialize(num)
@f = num
end
end
All of the tests pass until I get to the following:
require "temperature_object"
describe Temperature do
# 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
So, I'm thinking the problem is that I'm trying to go from Temperature.new, which takes a hash, to Celsius.new, which only takes a value. I'm getting an undefined method "has_key?" for nil:NilClass
error message. Do I need to set num as a hash value and assign it a key? If so, how do I do that? If not, any suggestions?
Upvotes: 0
Views: 2109
Reputation: 37419
Your problem is that you refer to @options
, but you don't assign it when creating an instance of Celsius
. You should call the super
constructor in your inherited classes:
class Celsius < Temperature
def initialize(num)
super(c: num)
end
end
class Fahrenheit < Temperature
def initialize(num)
super(f: num)
end
end
Now, when you call Celsius.new(50)
the initialize(opts)
will be called as if you called Temperature.new(c: 50)
, and all members will be properly assigned.
Upvotes: 2