【问题标题】:NoMethodError Ruby on Class InitializeNoMethodError Ruby 上的类初始化
【发布时间】:2014-10-02 13:54:01
【问题描述】:

我正在通过在线课程进行“课程介绍”练习。目标是创建一个用两个数字初始化的类Calculator。然后可以对数字进行加法、减法、乘法和除法。我的代码在本地环境中似乎可以正常工作:

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)>'

【问题讨论】:

  • attr_readerattr_accessor 是这里的正确答案。我只是想指出您对divide 的测试说“......返回一个'Float'是合适的”这可能应该读作“并返回一个Float”,因为它总是会返回一个Float,除非@987654329 @ 为 0 或无。在这种情况下,可能会返回 NaNInfinity,具体取决于 @x 的值。

标签: ruby class rspec nomethoderror


【解决方案1】:

只需添加这一行

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 中的 readerwriter 方法。

【讨论】:

    猜你喜欢
    • 2016-07-10
    • 1970-01-01
    • 2013-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-30
    相关资源
    最近更新 更多