例如,如果我们写下
class MyClass
attr_accessor :something
end
如果没有显式创建带有实例变量 @something
的初始化方法,Ruby 会自动创建吗?
例如,如果我们写下
class MyClass
attr_accessor :something
end
如果没有显式创建带有实例变量 @something
的初始化方法,Ruby 会自动创建吗?
实例变量在赋值之前不会被定义,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"]
将 something
设置为 nil
不会导致 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
有点类似。在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状态。