'self.method_name'和'class<<之间的区别自己在Ruby中

时间:2010-01-08 04:48:07

标签: ruby-on-rails ruby eigenclass

我试图将类的实例化限制为只有一个(不使用单例),但我不能。我尝试使用类变量(@@),但没有运气。 我用Google搜索并发现了这个:

class A 
  @count = 0 

  class << self 
    attr_accessor :count 
  end

  def initialize val 
    @a = val 
    self.class.count += 1 
  end 
end 

a=A.new 42 
b=A.new 43

我搜索了'类&lt;&lt;自我'解释希望找到一个更好的(或只是一个更简单和干净)但反对,没有运气。 最后,经过一些测试,我得出结论'class&lt;&lt; self '只是一个块包装器,您可以在其中定义方法。 那么,这是正确的吗?

问候!

4 个答案:

答案 0 :(得分:34)

class << self表示法打开了对象的本征类。特征类是一个匿名类,用于存储特定于实例的行为。在类的情况下,特征类有时被称为元类。

Ruby使用特征类来实现所谓的“类方法”(也称为静态方法)。

一个类(如moritz所述)也是Ruby中的一个对象,只要它是一个对象,它也有一个类。 Ruby中的类的类称为Class

任何语言中的“类方法”都是一个类是接收者的方法 - 即在类本身上直接调用该方法。

但是,为了在接收器上调用方法,必须在该接收器的类上定义方法。对于类,“类方法”可以Class类上实现为实例方法。

但是在Class上定义实例方法意味着所有类都可以访问那种不理想的类方法。

如前所述,输入本征类,对象的本征类是一个特殊类,用于存储该对象的唯一方法。在类的情况下,eigenclass是Class类的子类,并且是类的直接类。

因此,Ruby中的“类方法”只是在类的本征类上定义的“实例方法”。

def MyClass.my_method表示法实际上在MyClass的本征类上定义了my_method。如果你使用这种表示法,你可以通过(一段时间)而不实际理解本征类,因为你可以欺骗自己认为它只是Ruby定义'静态方法'的方式并继续认为Ruby的类模型类似于Java。但是,class << self符号不允许这样的解释,你必须接受本征类的现实。

总之,“类方法”实际上是在本征类上定义的“实例方法”,class << self使您可以访问本征类。

如需更多阅读,请查看以下链接:

http://banisterfiend.wordpress.com/2008/11/25/a-complete-ruby-class-diagram/

http://banisterfiend.wordpress.com/2008/10/25/the-secret-life-of-singletons/

http://www.klankboomklang.com/2007/09/21/the-singleton-class/

答案 1 :(得分:5)

从技术上讲,你是在类的元类上定义一个方法,而不是类本身。 Yehuda Katz在Ruby中对元类进行了很好的解释:http://yehudakatz.com/2009/11/15/metaprogramming-in-ruby-its-all-about-the-self/

答案 2 :(得分:2)

你的结论是对的。基本上,你必须记住,即使类是ruby中的对象,因此也有实例。并且使用类&lt;&lt;自我声明你只是在改变你对象的类实例。

答案 3 :(得分:2)

主题行与问题正文不完全匹配。我将解决主题行

中表达的问题

他们是同义词。

def self.foo
    ...
end

只是

的简写
class << self
    def foo
        ...
    end
end