4

我最近被以下代码难住了:

class Foo
  attr_accessor :n

  def initialize(i)
    @n = i
  end

  def val
    n
  end

  def bump!
    n += 1
  end
end

f = Foo.new(0)

puts f.val
f.bump!

puts f.val0成功并按预期打印出来。f.bump!导致以下NoMethodError

foo.rb:13:in `bump!': undefined method `+' for nil:NilClass (NoMethodError)
        from foo.rb:20:in `<main>'

知道为什么nnil表达式中n += 1吗?

相反,使用n = 1 + n会引发TypeError( nil cannot be coerced into Fixnum),n事实上也是如此nil

4

2 回答 2

9

即使您已经为 定义了一个n=方法Foo,Ruby 也不会让您在没有显式接收器的情况下从类中调用它self.n=

因此,当您编写时n += 1,它会被翻译成n = n + 1. n=没有显式接收器,因此 Ruby 创建了一个局部变量n(即nil)。因此ninn + 1指的是一个nil局部变量,给你NoMethodError.

attr_accessor仅供参考,除非您想在课堂n访问,否则您不需要!即使这样,当您编写实例方法时,您也应该只使用普通的实例变量。@n

于 2013-11-21T15:10:34.407 回答
1

你的错误在那里:

def bump!
  n += 1
end

使用self.n. 或@n

当你这样做:

attr_accessor :n

事实上你这样做:

def n
  @n
end

def n=(value)
  @n= value
end

当你这样做时n += 1,你使用一个局部变量(它是 niL)而不是使用由attr_accessor.

于 2013-11-21T14:59:29.127 回答