Ruby:从内部方法访问attr_accessor的方法

时间:2012-06-06 11:44:23

标签: ruby attr-accessor

我有一个代码:

class A
  attr_accessor :somevar

  def a
    somevar = 'something'
    puts @somevar
  end

  def b
    send :somevar=, 'something'
    puts @somevar
  end

end

A.new.a #=> nil
A.new.b #=> 'something'

为什么会有区别?为什么我不能通过编写器分配实例变量?但是为什么已经创建了局部变量而不是方法(setter)呢?

2 个答案:

答案 0 :(得分:7)

attr_accessor :somevar引用实例变量@somevar。实例变量必须以@符号开头。在方法中没有@符号的所有其他变量(如'somevar')只是该方法或范围的局部变量,而不是对象的实例变量。

因此,将方法“a”中的第一行更改为

@somevar = 'something'

将得出您期望的答案。

相关说明:您不必在Ruby中声明实例变量,只需使用@somevar类型表示法创建它们。 attr_accessor方法为该实例变量创建setter和getter。

Ruby中的方法附加到对象,因此为了让A类调用自己的somevar setter方法,您需要编写self.somevar = 'something',否则Ruby解析器会认为您只是创建了一个局部变量。 / p>

这可能令人困惑,因为您可以通过以下方式从a调用方法b

def b
  send :somevar=,'something'
  puts @somevar
  a  # would invoke its own method 'a'
end

但是setter方法somevar=与创建具有相同表示法的局部变量不明确:

somevar='something'  # Ruby assumes you want to create a local variable

所以要调用somevar setter方法,你需要明确地说你在自己上调用方法:

self.somevar = 'something'

当您调用send :somevar=,'something'时,您也调用了somevar实例方法。

答案 1 :(得分:1)

这是因为方法a正在创建一个名为somevar的局部变量。这只是Ruby的一个小怪癖。您可以通过self.somevar = 'something'@somevar = 'something'来解决此问题。