16

例如,如果我们写

class MyClass
  attr_accessor :something
end

但是没有显式创建带有实例变量的初始化方法@something,Ruby会自动创建它吗?

4

2 回答 2

31

不。实例变量在您分配给它们之前不会被定义,并且attr_accessor不会自动这样做。

尝试访问未定义的实例变量会返回nil,但没有定义该变量在您写信给它们之前,它们实际上并没有被定义。attr_accessor依赖于这种行为,除了定义一个 getter/setter 之外什么都不做。

您可以通过签出来验证这一点.instance_variables

class Test
  attr_accessor :something
end

的新实例x没有实例变量:

x = Test.new # => #<Test:0xb775314c>
x.instance_variables # => []

调用 getter 不会导致@something定义:

x.something # => nil
x.instance_variables # => []

调用 setter确实会导致@something定义:

x.something = 3 # => 3
x.instance_variables # => ["@something"]

设置somethingnil不会导致instance_variables恢复,因此我们可以确定返回的第一个空数组不仅仅是instance_variables省略nil值的情况:

x.something = nil # => nil
x.instance_variables # => ["@something"]

您还可以验证这不仅仅是特定于以下的行为attr_accessor

class Test
  def my_method

    @x # nil

    instance_variables # []

    @x = 3 

    instance_variables # ["@x"]
  end 
end

Test.new.my_method
于 2013-03-20T02:57:33.033 回答
2

有点。在 Ruby 中,实例变量是在首次分配时创建的。这对程序员来说是完全透明的。在分配之前,它们默认为 nil。

前任:

class Foo
  attr_accessor :bar
  def baz
    @nonexistant
  end
end
f.bar #=> nil
f.baz #=> nil
f.bar = 4
f.bar #=> 4

在您为实例变量赋值之前,它会处于未定义的 nil 状态。

于 2013-03-20T02:54:53.893 回答