在初始化中使用访问器进行设置会导致nil属性

时间:2016-05-15 00:33:18

标签: ruby

为什么最后一行导致nil而不是15

class TextC
  attr_accessor :thing1  
  def initialize
    thing1 = 15
    puts "thing: #{thing1}"
    some_method
  end  
  def some_method
    puts "ho there, wanderer"
  end
end  
tc = TextC.new
# thing: 15
# ho there, wanderer
# => #<TextC:0x007fe5617f1b30>
tc.thing1
# => nil

我们已经确定Ruby将thing1 = value视为局部变量的设置,但为什么呢?

为什么访问器方法不会被推断为我想要做的事情,但some_method呢? attr_accessor结果是仅在初始化后计算的吗?

2 个答案:

答案 0 :(得分:2)

attr_accessor :thing1定义了一个访问实例变量@thing1的属性。实例变量始终以@为前缀。

分配thing1 = 15会在initialize方法中创建一个局部变量。它不调用属性writer,因此未设置实例变量@thing1的值。由于尚未分配@thing1,因此属性阅读器tc.thing1将返回nil

thing1 = 15等分配表达式,没有明确的接收者(tc.thing1 = 15)且不是实例或类变量(@thing1 = 15@@thing1 = 15在Ruby中,总是定义和/或分配一个局部变量。要调用属性writer(并让它设置实例变量),您需要明确指定接收器,例如self.thing1 = 15

原因是因为在Ruby中,在分配变量之前不要声明变量。像thing1 = 15这样的表达式是不明确的,因此Ruby选择使它始终引用局部变量。

在没有显式接收器的情况下调用非属性编写器的方法(名称不以=结尾的方法)没有问题,因为没有歧义。因此,some_method中的initialize表达式将调用方法some_method

attr_accessor定义的属性可立即使用。在任何方法中都会遇到相同的行为,而不仅仅是initialize

答案 1 :(得分:0)

由于@thing1未初始化,并且在调用时,默认情况下会返回nil