3

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

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

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

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

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

[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 进行。那我在问什么?

  • 我做对了吗?
  • 我得到的红宝石术语正确吗?
  • 在正确设计的应用程序中,任何对类实例变量的实际使用都有意义?或者这些仅仅是更好的@@class 变量?
4

3 回答 3

9

我很困惑地发现这@variable可能意味着两种截然不同的东西。

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

让类成为对象的美妙之处恰恰在于它@variable总是意味着完全相同的东西

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

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

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

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

于 2014-07-29T21:39:58.380 回答
5
  1. 首先,要理解实例变量,需要知道 this -类是对象

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

  2. 然后@@insself.

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

  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
    
于 2014-07-30T01:41:54.707 回答
0

一切对我来说都是正确的。

类变量将通过继承传递,而类上的实例变量则不会。(src:Ruby 类实例变量与类变量

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

于 2014-07-29T21:43:56.353 回答