ruby:类实例变量vs实例变量

ako*_*nov 3 ruby instance-variables class-instance-variables

我的想法是为那些来自java背景的人创建一个社区wiki,因为阅读了大量的解释,直到我真正尝试了几件事情并且拼图的各个部分开始找到他们的位置时,我无法理解任何事情.但我首先需要确保我做对了.从这样的背景来看,我发现这@variable可能意味着两件截然不同的事情让我非常困惑.这是一个例子:

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

  def initialize()
    @ins = "wtf?"
  end
  def ins2
    puts @ins
  end
end
Run Code Online (Sandbox Code Playgroud)

据我所知,第一个@ins是表示类的对象的实例变量Test.第二个@ins是类对象中的实例变量Test.

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

[14] pry(main)> test.ins2
wtf?
Run Code Online (Sandbox Code Playgroud)

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

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

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

[16] pry(main)> Test.ins
gah
Run Code Online (Sandbox Code Playgroud)

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

[17] pry(main)> Test.ins2
NoMethodError: undefined method `ins2' for Test:Class
Run Code Online (Sandbox Code Playgroud)

我们通过类调用一个对象方法,这是不正确的抛出NoMethodError.

以上所有都是用ruby 2.0进行的.那我在问什么?

  • 我做对了吗?
  • 我的红宝石术语是否正确?
  • 在正确设计的应用程序中有意义的类实例变量的任何实际用法?或者这些只是更好的@@类变量?

Jör*_*tag 9

我发现这@variable可能意味着两件截然不同的事情,这让我非常困惑.

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

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

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

没有类方法这样的东西:它只是一个正常的单例方法,它碰巧是一个实例Class.(实际上,也没有单例方法这样的东西:它只是对象的单例类的普通实例方法.)

注意:Rubyists可以在随意对话中使用术语"类方法".但这并不意味着类方法确实存在,它只意味着"类对象的单例类的实例方法"是满口的.重要的是:因为类是对象,它们的工作方式与所有其他对象完全相同.他们可以有实例方法(在类中定义Class或继承Module,Object,KernelBasicObject),也可以有"特殊方法"(这确实是他们各自的单类的实例方法),也可以有实例变量.

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


Win*_*r C 5

  1. 首先,要理解实例变量,需要知道这个——类是对象

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

  2. 然后,每个实例变量(标有IDS@一样@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
    
    Run Code Online (Sandbox Code Playgroud)