【问题标题】:ruby: class instance variables vs instance variablesruby:类实例变量与实例变量
【发布时间】:2014-09-21 09:51:46
【问题描述】:

我的想法是为来自java 背景的人创建一个社区 wiki,因为阅读了很多解释,直到我真正尝试了一些事情并且拼图的碎片开始出现之前,我无法理解任何东西找到他们的位置。但我首先需要确保我做对了。来自这样的背景让我很困惑地发现@variable 可能意味着两个非常不同的东西。 这是一个例子:

class Test
  @ins = "gah"
  def self.ins
    puts @ins
  end

  def initialize()
    @ins = "wtf?"
  end
  def ins2
    puts @ins
  end
end

据我了解,第一个@ins 是代表Test 类的对象的实例变量。第二个@insTest 类对象中的实例变量。

现在事情开始对我有意义了。这里有几个例子:

[14] pry(main)> test.ins2
wtf?

我们正在调用一个对象的方法,它返回对象的实例变量。

[15] pry(main)> test.ins
NoMethodError: undefined method `ins' for #<Test:0x000000017d9348 @ins="wtf?">

我们试图通过一个对象调用一个类方法,这个方法是类的所以我们得到NoMethodError

[16] pry(main)> Test.ins
gah

我们正在调用一个类方法,所以它可以正确地看到类对象的实例变量。

[17] pry(main)> Test.ins2
NoMethodError: undefined method `ins2' for Test:Class

我们正在通过不正确的类调用对象方法,因此抛出NoMethodError

以上所有操作都是使用 ruby​​ 2.0 执行的。那我在问什么?

  • 我说对了吗?
  • 我得到的 ruby​​ 术语正确吗?
  • 在正确设计的应用程序中有意义的类实例变量的任何实际用法?或者这些仅仅是更好的@@class 变量?

【问题讨论】:

  • 重量*? :D 有趣的帖子。 +1
  • 您可以将其称为类方法,但从技术上讲并非如此。这是单例类的方法看这个youtube.com/watch?v=X2sgQ38UDVY
  • @SamD,谢谢你的视频,我一定会看的。但我不明白为什么要称它为“单例类”。这意味着还有其他类型的类。称它为类对象的方法不是更好吗?所以它将是“类对象”与“类实例”,前者是代表类的对象,后者是该类的对象?
  • Singleton 类是一个匿名类,当你定义 self.method 匿名类(singleton)被初始化并添加到它的方法时,它隐藏在后台。之后的任何 self.method 都会添加到单例中
  • @SamD,对不起,我无法理解。也许它在我稍后会观看的视频中。但是当一切都是对象时,class 是什么?在任何情况下,它都会变得离题。我要问的是,当所有类都像您上面描述的那样时,为什么将其称为“单例类”而不是“类”。

标签: ruby instance-variables class-instance-variables


【解决方案1】:

我很困惑地发现 @variable 可能意味着 2 个非常不同的东西。

不,它没有。类是对象,就像任何其他对象一样。它们可以像任何其他对象一样具有实例变量。它们可以像任何其他对象一样具有实例方法。事实上,与 Java 不同,Java 有三种不同的“方法”(实例方法、静态方法和构造函数),而在 Ruby 中,只有一种方法:实例方法。

将类作为对象的美妙之处恰恰在于@variable 总是意味着完全相同

没有类实例变量这样的东西:它只是一个普通的实例变量,就像任何其他的一样。该对象恰好是Class 的一个实例,但这不会改变实例变量的性质。 String 类对象的实例变量不是字符串实例变量,它只是一个实例变量。同样,Class 类的对象的实例变量只是一个实例变量。

没有类方法这样的东西:它只是一个对象的普通单例方法,恰好是Class 的一个实例。 (实际上也不存在单例方法,它只是对象的单例类的普通实例方法。)

注意:Ruby 爱好者可能会在闲聊中使用术语“类方法”。但这并不意味着类方法确实存在,它只是意味着“类对象的单例类的实例方法”是一个拗口。重要的是:因为类是对象,所以它们完全像所有其他对象一样工作。它们可以有实例方法(在类Class 中定义或从ModuleObjectKernelBasicObject 继承),它们可以有“单例方法”(实际上是它们各自单例类的实例方法),它们可以有实例变量。

他们可以有类变量(@@variables)……这些很奇怪。忽略它们:-)

【讨论】:

  • 很抱歉,但是按照这种逻辑,我们可以说没有什么不同,因为一切实际上都是比特 :) 在典型的 OO 设计中,一个实例变量和一个类实例变量(我认为我们同意定义)与程序在语义上是不同的东西。当我们说话时,我们需要一些术语来轻松地相互理解。我认为这些概念没有清楚地描述是 ruby​​ 文档的一个缺陷(至少我找不到明确的解释)。 +1 提供有趣的细节。
【解决方案2】:

在我看来一切都是正确的。

类变量将通过继承传递下来,而类上的实例变量则不会。 (来源:Ruby class instance variable vs. class variable

就设计而言,我倾向于完全避免类变量(我宁愿使用单例),但如果我必须选择一个,我可能会选择类变量而不是类实例变量以避免混淆。

【讨论】:

    【解决方案3】:
    1. 首先,要了解实例变量,需要了解这一点 - 类是对象

      所有类都是Class(阅读文档)的实例,它继承自Object。这就是为什么类是对象

    2. 然后,每个实例变量(标有@ 的id,如@ins)都在self 中定义。

      self是一个类时,它们是类的实例变量(类实例变量)。 当self是一个对象时,它们是对象的实例变量(instance variables)。

    3. 在不同的代码范围内,self 代表不同的东西。

      class Test
        # class scope, uncomment following line to see the value of self
        # p self
        @ins = "gah"
        def self.ins
          # class scope
          # p self
          puts @ins
        end
      
        def initialize()
          # object scope
          # p self
          @ins = "wtf?"
        end
        def ins2
          # object scope
          # p self
          puts @ins
        end
      end
      

    【讨论】:

      猜你喜欢
      • 2013-03-24
      • 1970-01-01
      • 2021-07-29
      • 1970-01-01
      • 1970-01-01
      • 2013-11-26
      • 2010-10-28
      • 2012-06-11
      • 1970-01-01
      相关资源
      最近更新 更多