5

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

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

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

问候!

4

4 回答 4

35

class << self符号打开了对象的特征类。eigenclass 是一个匿名类,它存储特定于实例的行为。在类的情况下,特征类有时称为元类。

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

一个类(如 moritz 所说)在 Ruby 中也是一个对象,就它是一个对象而言,它也有一个类。Ruby 中类的类称为Class.

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

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

但是在 on 上定义实例方法Class意味着所有类都可以访问该类方法,这并不理想。

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

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

def MyClass.my_method符号实际上是my_method在 MyClass 的特征类上定义的。如果您使用这种表示法,您可以(暂时)在没有真正理解特征类的情况下通过,因为您可以欺骗自己认为这只是 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/

于 2010-01-08T06:52:41.173 回答
5

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

于 2010-01-08T05:39:07.537 回答
3

主题行与问题的正文不太匹配。我将解决主题行中表达的问题:

它们是同义词。

def self.foo
    ...
end

只是简写

class << self
    def foo
        ...
    end
end
于 2012-02-19T08:45:30.370 回答
2

你的结论是对的。基本上,您必须记住,即使类也是 ruby​​ 中的对象,因此也有实例。而使用 class << self 语句,您只是在更改对象的该类实例。

于 2010-01-08T04:54:23.207 回答