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

What does it mean that `attr_accessor` / `attr_reader` create an instance variable?

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

[...] creating an instance variable (@name) and a corresponding access method [...]

attr_reader 的文档也是如此:

Creates instance variables and corresponding methods [...]

我理解第二部分,即 attr_accessorattr_reader 创建方法,但我不明白第一部分。

他们"create an instance variable"是什么意思?

这是文档中的 bug/misleading 措辞。 attr_reader/attr_accessor 本身不会创建任何变量。他们怎么能它们在 class 实例生命周期之外工作。甚至读访问也不会使实例变量变得生动。只有写入权限才能创建它们。

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

The documentation for attr_accessor explicitly says that it creates an instance variable:

[...] creating an instance variable (@name) and a corresponding access method [...]

attr_reader 的文档也是如此:

Creates instance variables and corresponding methods [...]

我理解第二部分,即 attr_accessorattr_reader 创建方法,但我不明白第一部分。

他们"create an instance variable"是什么意思?

该文档即使不是完全错误,至少也具有误导性。他们创造方法,仅此而已。在大多数 Ruby 实现中,实现是在宿主语言中(例如 YARV 的 C,JRuby 的 Java)具有对实现内部的特殊特权访问,但实际上,您可以用普通的 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