如何读取类的实例变量范围和可见性

时间:2017-01-13 17:01:41

标签: ruby

如果使用attr_accessor在类中设置了类的实例变量值,为什么不能读取它?

是因为实例变量是“私有的吗?”

以这种方式设置属性:

class Test
  attr_accessor :magic
end

bob = Test.new
bob.magic = "cat" #set 
print bob.magic #read

以这种方式设置属性失败:

class Test
  attr_accessor :magic
  @magic = "spell"
end

bob = Test.new
print bob.magic #this resolves to 'nil'

4 个答案:

答案 0 :(得分:3)

实例变量和类实例变量之间存在显着差异。

class Test
  @magic = "spell" # class instance var, since the scope is class 

  def initialize
    @magic = 42 # instance var, scope is instance
  end
end

这两个人住在一起,因为他们是在不同的对象上定义的:

Test.instance_variable_get(:@magic) #⇒ "spell"
Test.new.instance_variable_get(:@magic) #⇒ 42

那就是说,attr_accessor从范围读取变量,它被定义为。你的是在类范围内定义的,因此它读取实例范围的变量。

要读取类实例变量,请在类'singleton class level:

上定义attr_accessor
class Test
  singleton_class.send :attr_accessor, :magic # reads class instance var ⇓
  @magic = "spell" # class instance var, since the scope is class 

  attr_accessor :magic # reads instance var ⇓
  def initialize
    @magic = 42 # instance var, scope is instance
  end
end

Test.magic
#⇒ "spell"
Test.new.magic
#⇒ 42

答案 1 :(得分:2)

您可以通过在@magic单身类中定义attr_accessor来访问测试的Test

class Test
  @magic = "spell"

  class << self
    attr_accessor :magic
  end
end

Test.magic #=> "spell"

答案 2 :(得分:2)

您应该将:null_session声明/赋值移到构造函数中,如下所示:

@magic

在任何方法(self)之外声明实例变量(class Test attr_accessor :magic def initialize @magic = "spell" end end bob = Test.new print bob.magic #spell )时,类实例无法访问它。

答案 3 :(得分:2)

实例变量属于对象(又名“实例”),这就是它们被称为实例变量的原因。

在第一个示例中,您将@magic上的实例变量bob设置为'cat',然后您正在@magic上读取实例变量bob

在第二个示例中,您在@magic上设置了实例变量Test(这是一个与bob完全不同的对象),然后您正在读取实例变量{{1来自@magic的尚未设置的,未初始化的实例变量计算为bob

记住:类就像任何其他对象一样是对象。它们可以像任何其他对象一样拥有实例变量。