2014-10-02 81 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中的方法。