Ruby的attr_accessor是否会自动为属性创建实例变量?

16

例如,如果我们写下

class MyClass
  attr_accessor :something
end

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

2个回答

32

实例变量在赋值之前不会被定义,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

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状态。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接