我试图将类的实例化限制为只有一个(不使用单例),但我不能。我尝试使用类变量(@@),但没有运气。 我用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 '只是一个块包装器,您可以在其中定义类方法。 那么,这是正确的吗?
问候!
答案 0 :(得分:34)
class << self
表示法打开了对象的本征类。特征类是一个匿名类,用于存储特定于实例的行为。在类的情况下,特征类有时被称为元类。
Ruby使用特征类来实现所谓的“类方法”(也称为静态方法)。
一个类(如moritz所述)也是Ruby中的一个对象,只要它是一个对象,它也有一个类。 Ruby中的类的类称为Class
。
任何语言中的“类方法”都是一个类是接收者的方法 - 即在类本身上直接调用该方法。
但是,为了在接收器上调用方法,必须在该接收器的类上定义方法。对于类,“类方法”可以在Class
类上实现为实例方法。
但是在Class
上定义实例方法意味着所有类都可以访问那种不理想的类方法。
如前所述,输入本征类,对象的本征类是一个特殊类,用于存储该对象的唯一方法。在类的情况下,eigenclass是Class
类的子类,并且是类的直接类。
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