Ruby 'attr\u accessor`/'attr\u reader`创建实例变量是什么意思?

Ruby 'attr\u accessor`/'attr\u reader`创建实例变量是什么意思?,ruby,instance-variables,attr-accessor,Ruby,Instance Variables,Attr Accessor,的文档明确说明它创建了一个实例变量: […]创建实例变量(@name)和相应的访问方法[…] 与以下文件一样: 创建实例变量和相应的方法[…] 我理解第二部分,即attr\u访问器和attr\u阅读器创建方法,但我不理解第一部分 他们“创建实例变量”是什么意思?这是文档中的错误/误导性措辞。attr\u读取器/attr\u访问器本身不创建任何变量。他们怎么能?它们在类实例生命周期之外工作。即使是读访问也不能使实例变量变为现实。只有写访问才能创建它们 class Foo attr_access

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

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

与以下文件一样:

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

我理解第二部分,即
attr\u访问器
attr\u阅读器
创建方法,但我不理解第一部分


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

这是文档中的错误/误导性措辞。
attr\u读取器
/
attr\u访问器
本身不创建任何变量。他们怎么能?它们在类实例生命周期之外工作。即使是读访问也不能使实例变量变为现实。只有写访问才能创建它们

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
的文档明确说明它创建了一个实例变量:

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

与以下文件一样:

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

我理解第二部分,即
attr\u访问器
attr\u阅读器
创建方法,但我不理解第一部分

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

如果不是完全错误的话,文档至少是误导性的。他们创造方法,仅此而已。在大多数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

从技术上讲,访问器可以在初始化过程中添加一个步骤,将所述实例变量设置为
nil
。但正如您所演示的,情况并非如此,重要的是要记住,Ruby核心团队并没有维护这一点。它有时推测某些事情应该是稳定的,而官方没有这样的说法。其他时候,它对实现的推测是不正确的。@ndn:这些年来,我一直认为ruby文档是根据源代码注释自动生成的。你是说不是这样头脑风暴:@SergioTulentsev,(但它仍然不是由核心团队维护的)。所以代码中的注释是错误的…@ndn:如果我们想学究的话,技术上是错误的。也许这些评论的作者想说得更笼统一些。“创建实例变量”,如“与此访问器名称匹配的实例变量将在对象生命周期的某个时刻成为一件事情”。或者我在这里扮演魔鬼代言人的角色太多了:)@ndn:看来我们应该为14年前写的那篇评论责怪戴夫·托马斯。我们可以在twitter上问他:)YARV的实现还执行一个检查:如果属性名不是有效的实例变量名,则会引发
namererror
。e、 g:
attr\u读取器“1”
导致
无效的属性名称“1”
。也许文件是指那张支票。