在Ruby中,我能否从实例方法中访问类实例变量?

4
以下代码在类方法中设置了 C 类的类变量,并显示它可以从实例方法中访问:
class C
  def self.set_a
    @@a = 1
  end

  def get_a
    @@a
  end
end

C.set_a
C.new.get_a #=> 1

如果我在类方法 set_a 中将@@a替换为@a,那么它会创建一个类实例变量而不是一个类变量,我还能从实例方法 get_a 中访问它吗?


我假设你知道不能写成 def get_a; @a; end,因为 c = C.new; c.get_a 会返回 c 实例变量 @a 的值。因此,在 get_a 中需要使用两个方法来获取类实例变量 @a 的值。第一个方法是获取 c 的类;第二个方法在 c 的类上调用以获取变量的值。 - Cary Swoveland
1
实例变量属于实例。这就是为什么它们被称为实例变量。CC.new是两个完全不同的对象,彼此之间没有任何关联。实例变量的整个意义在于一个对象不能访问另一个对象的实例变量,除非该对象以某种方式明确地将其公开。 - Jörg W Mittag
1个回答

4
我认为您不能直接引用它。类是一个对象,实例变量是私有/内部的对象属性。您可以通过在类上使用 instance_variable_get 或将其包装在getter方法中来访问它。
在Rails中,您可以使用 class_variable 来方便地设置和访问类级别的变量。

你的意思是说你不能直接引用它吗?instance_variable_get不是一个完全好用、常见的方法吗?我认为你应该说“是的,使用instance_variable_get”。 - Cary Swoveland
1
我的意思是你不能使用@@var或者@var的形式来引用它们,你需要使用一个方法来访问它。 - mrzasa
1
是的,我明白了,但 OP 只是说,“...我还能从实例方法 get_a 中访问它吗?”。没有提到不使用方法。此外,访问器的提及有些不相关,因为似乎 OP 只想更改 get_a,即使有访问器,你仍然会在 get_a 中使用方法来访问它。当然,这只是小问题。 - Cary Swoveland
1
@CarySwoveland 在这个意义上,几乎所有的变量都可以从任何地方访问(唯一的例外是局部变量)。使用 class_evalinstance_evalsend,您可以绕过任何作用域限制,即使没有像 instance_variable_get 这样的标准接口。 - Max

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