Ruby 如何读取同一类中由访问器设置的实例变量?

Ruby 如何读取同一类中由访问器设置的实例变量?,ruby,instance-variables,accessor,Ruby,Instance Variables,Accessor,我很好奇,在为实例变量定义了访问器的类中,访问实例变量的首选方法是什么 一种方法是直接引用实例变量: class Example attr_accessor :attribute def meth puts @attribute end end 另一种方法是调用访问者创建的读取器: class Example attr_accessor :attribute def meth puts attribute end end 这是一个小的区别,但我很好

我很好奇,在为实例变量定义了访问器的类中,访问实例变量的首选方法是什么

一种方法是直接引用实例变量:

class Example
  attr_accessor :attribute

  def meth
    puts @attribute
  end
end
另一种方法是调用访问者创建的读取器:

class Example
  attr_accessor :attribute

  def meth
    puts attribute
  end
end

这是一个小的区别,但我很好奇哪一个是首选的方法,为什么。与直接实例变量访问相比,我在读卡器上看到的唯一优势是更容易在测试中存根读卡器。

最好通过访问器。例如,如果直接访问实例变量,然后使用读取器转换该值,那么直接访问实例变量将看不到该更改

当您想使用访问器设置实例变量的值时,使用访问器而不是直接访问实例变量会导致一个小问题

通常,当你写作时:

some_meth 10
age = 10
…ruby将其解释为:

self.some_meth(10)
self.age=(10)
但如果你写:

some_meth 10
age = 10
…ruby不会将其解释为:

self.some_meth(10)
self.age=(10)
相反,ruby将创建一个名为
age
的局部变量,并将其设置为10,这对名为
@age
的实例变量没有影响

为了调用@age的setter,您必须显式地编写
self

self.age = 10
下面是一个完整的示例:

class Dog
  attr_reader :age

  def age=(val)
    @age = val * 7
  end

  def initialize val 
    self.age = val  #age = val  will not call the setter
  end

end

d = Dog.new 10
puts d.age  #=> 70
事实上,您还为访问者添加了2张“投票”,尽管差别并没有那么大。但是访问器只是将“可用性”值添加到代码中。