2014-10-02 88 views
2

我正在通过在线课程进行“课程介绍”练习。我们的目标是创建一个用两个数字初始化的类Calculator。这些数字可以被加,减,乘,除。我的代码似乎对当地环境功能:NoMethodError Ruby on Class初始化

class Calculator 
    def initialize(x,y) 
    @x, @y = x, y 
    end 
    def self.description 
    "Performs basic mathematical operations" 
    end 
    def add 
    @x + @y 
    end 
    def subtract 
    @x - @y 
    end 
    def multiply 
    @x * @y 
    end 
    def divide 
    @x.to_f/@y.to_f 
    end 
end 

但是,该网站有Rspec的规格:

describe "Calculator" do 
    describe "description" do 
    it "returns a description string" do 
     Calculator.description.should == "Performs basic mathematical operations" 
    end 
    end 
    describe "instance methods" do 
    before { @calc = Calculator.new(7, 2) } 
    describe "initialize" do 
     it "takes two numbers" do 
     expect(@calc.x).to eq(7) 
     expect(@calc.y).to eq(2) 
     end 
    end 
    describe "add" do 
     it "adds the two numbers" do 
     expect(@calc.add).to eq(9) 
     end 
    end 
    describe "subtract" do 
     it "subtracts the second from the first" do 
     expect(@calc.subtract).to eq(5) 
     end 
    end 
    describe "multiply" do 
     it "should return a standard number of axles for any car" do 
     expect(@calc.multiply).to eq(14) 
     end 
    end 
    describe "divide" do 
     it "divides the numbers, returning a 'Float' if appropriate" do 
     expect(@calc.divide).to eq(3.5) 
     end 
    end 
    end 
end 

和网站的规范抛出一个NoMethodError:

NoMethodError 
undefined method `x' for #<Calculator:0x007feb61460b00 @x=7, @y=2> 
    exercise_spec.rb:14:in `block (4 levels) in <top (required)>' 
+0

'attr_reader'或'attr_accessor'在这里是正确的答案。我只是想说明你对'divide'的测试说“...返回一个'Float'是合适的”这可能应该是“读取并返回一个Float”,因为它总是会返回一个'Float',除非'@ y'是0或零。在这种情况下,可能会根据“@ x”的值返回'NaN'或'Infinity'。 – engineersmnky 2014-10-02 14:26:32

回答

3

只需添加这行

attr_reader :x, :y 

以下是更正代码:

class Calculator 
    attr_reader :x, :y 

    def initialize(x,y) 
    @x, @y = x, y 
    end 
    def self.description 
    "Performs basic mathematical operations" 
    end 
    def add 
    # once you defined reader method as above you can simple use x to get the 
    # value of @x. Same is true for only y instead of @y. 
    x + y 
    end 
    def subtract 
    x - y 
    end 
    def multiply 
    x * y 
    end 
    def divide 
    x.to_f/y.to_f 
    end 
end 

看看下面的规范代码: -

describe "initialize" do 
     it "takes two numbers" do 
     expect(@calc.x).to eq(7) 
     expect(@calc.y).to eq(2) 
     end 
     #... 

要调用@calc.x@calc.y。但是您没有定义任何名为#x#y的方法作为类Calculator中的实例方法。这就是为什么你得到了非常明确的例外,如NoMethod error

当你会写attr_reader :x, :y它会为你在内部创建这些方法。阅读answer了解阅读器书写器 Ruby中的方法。