`attr_accessor` /`attr_reader`创建实例变量是什么意思?

时间:2017-05-22 09:08:09

标签: ruby instance-variables attr-accessor

attr_accessor的文档明确说明它创建了一个实例变量:

  

[...]创建实例变量(@name)和相应的访问方法[...]

attr_reader的文档一样:

  

创建实例变量和相应的方法[...]

我理解第二部分,即attr_accessorattr_reader创建方法,但我没有得到第一部分。

他们“创建一个实例变量”是什么意思?

2 个答案:

答案 0 :(得分:4)

这是文档中的错误/误导性措辞。 attr_reader / attr_accessor本身不会创建任何变量。他们怎么样?它们在类实例生命周期之外工作。甚至读取访问也不会使实例变量变为现实。只有写入权限才能创建它们。

class Foo
  attr_accessor :bar
end

foo = Foo.new
foo.instance_variables # => []
foo.bar # try read ivar
foo.instance_variables # => [], nope, not yet
foo.bar = 2 # write ivar
foo.instance_variables # => [:@bar], there it is

答案 1 :(得分:2)

  

attr_accessor的文档明确说明它创建了一个实例变量:

     
    

[...]创建实例变量(@name)和相应的访问方法[...]

  
     

attr_reader的文档一样:

     
    

创建实例变量和相应的方法[...]

  
     

我理解第二部分,即attr_accessorattr_reader创建方法,但我没有得到第一部分。

     

他们"创建实例变量"是什么意思?

如果没有明显的错误,文档至少会产生误导。他们创造方法,仅此而已。在大多数Ruby实现中,实现是使用宿主语言(例如,C表示YARV,Java表示JRuby),具有对实现内部的特殊权限,但实际上,您可以用纯Ruby编写它们:

class Module
  def attr_reader(*attrs)
    attrs.each do |attr|
      define_method(attr) do
        instance_variable_get(:"@{attr}")
      end
    end
  end

  def attr_writer(*attrs)
    attrs.each do |attr|
      define_method(:"{attr}=") do |val|
        instance_variable_set(:"@{attr}", val)
      end
    end
  end

  def attr_accessor(*attrs)
    attr_reader(*attrs)
    attr_writer(*attrs)
  end
end