Ruby attr_reader和+ =

时间:2013-11-21 14:57:28

标签: ruby attr-accessor

我最近被以下代码困扰:

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.val成功并按预期打印0f.bump!会导致以下NoMethodError

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

在表达式n中知道niln += 1的原因是什么?

使用n = 1 + n会引发TypeErrornil cannot be coerced into Fixnum),因此n实际上是nil

2 个答案:

答案 0 :(得分:7)

即使您为n=定义了Foo方法,Ruby也不允许您在没有明确接收者的情况下从中调用它,即{{1 }}

因此,当您撰写self.n=时,会将其转换为n += 1n = n + 1没有明确的接收者,所以Ruby创建了一个局部变量n=n)。因此,nil中的n引用n + 1局部变量,为您提供nil

仅供参考,您不需要NoMethodError,除非您希望attr_accessor可以在课程 之外访问!即便如此,当您编写实例方法时,您应该只使用普通的实例变量n

答案 1 :(得分: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创建的两种方法。