例如,如果我们写
class MyClass
attr_accessor :something
end
Run Code Online (Sandbox Code Playgroud)
但没有使用实例变量显式创建初始化方法@something,Ruby会自动创建它吗?
mea*_*gar 30
否.实例变量在分配给它们之前不会定义,attr_accessor也不会自动执行.
尝试访问未定义的实例变量会返回nil,但不会定义该变量.在你写信之前,它们实际上并没有被定义.attr_accessor依赖于这种行为,除了定义一个getter/setter之外什么都不做.
您可以通过以下方式验证.instance_variables:
class Test
attr_accessor :something
end
Run Code Online (Sandbox Code Playgroud)
x没有实例变量的新实例:
x = Test.new # => #<Test:0xb775314c>
x.instance_variables # => []
Run Code Online (Sandbox Code Playgroud)
调用getter不会导致@something定义:
x.something # => nil
x.instance_variables # => []
Run Code Online (Sandbox Code Playgroud)
调用setter 会导致@something定义:
x.something = 3 # => 3
x.instance_variables # => ["@something"]
Run Code Online (Sandbox Code Playgroud)
设置something回nil不会导致instance_variables恢复,因此我们可以确定返回的第一个空数组不仅仅是instance_variables省略nil值的情况:
x.something = nil # => nil
x.instance_variables # => ["@something"]
Run Code Online (Sandbox Code Playgroud)
您还可以验证这不仅仅是针对attr_accessor以下行为:
class Test
def my_method
@x # nil
instance_variables # []
@x = 3
instance_variables # ["@x"]
end
end
Test.new.my_method
Run Code Online (Sandbox Code Playgroud)