如果使用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'
答案 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
。
记住:类就像任何其他对象一样是对象。它们可以像任何其他对象一样拥有实例变量。