我继续研究Ruby,另一个问题发生在我身上。我知道当我们在类上定义一个类方法时,它创建了一个单例类来获取该方法的定义,从那时起,该方法就是该单例类的实例方法(我从测试中得到了这个结论,但是我可能错了,所以请随意纠正我。)
我的问题是,如果在单例类上将方法定义为该类的实例方法,我如何使用X.classMethod在类X上调用类方法(我不知道我该怎么做。是怎么回事。)它让我更加困惑,因为我注意到(运行一些测试)类的单例类甚至与它来自的类没有层次关系,所以,如何将类方法调用解析为单例类?更确切地说:类如何在单例类上调用方法,该方法是一个实例方法,没有任何实例。
我希望我没有让你感到困惑。
再次感谢你。
答案 0 :(得分:2)
我将从下面的例子开始:
class Foo
def self.bar
puts 12
end
end
Foo.singleton_methods # => [:bar]
Foo.ancestors # => [Foo, Object, Kernel, BasicObject]
在Ruby类中也是对象。现在,#bar
是Foo
的单例方法。当您执行Foo.bar
时,Foo
首先在其单例类中搜索,然后向上搜索单例类的祖先链。 singleton class 是一种ghost类,因此它在祖先链中是不可见的,但它就在那里。它被语言设计者有意隐藏在Foo.ancestors
的输出中。 单例方法由对象(此处为 FOO )直接调用,在该类上创建了单例(每个对象基础类)。 您无法创建单件类的实例。
这是一个证据:
Foo.singleton_class.new # can't create instance of singleton class (TypeError)
还要记住,一个类的单例方法在这里说Bar
,也可以用于它的后代类(这里是Foo
)。因为当您编写Foo
时,Bar的元类成为class Foo < Bar..
的元类的超类。
class Bar
def self.biz
puts 11
end
end
class Foo < Bar
def self.bar
puts 12
end
end
Bar.singleton_class # => #<Class:Bar>
Foo.singleton_class.superclass # => #<Class:Bar>
答案 1 :(得分:1)
对于您的第一个问题,假设X类包含以下内容:
class X
def self.class_method
end
end
然后class_method
是X.singleton_class
的实例方法,您可以通过运行
X.singleton_class.instance_methods(false)
# ==> [:class_method]
要了解单例类如何与类层次结构相关,我发现这样的图表很有用(eigenclass是singleton类的另一个名称):
在那个图之后,我认为它有点复杂,但是使用逻辑,似乎更有必要,假设以下假设成立:
从1开始,我们可以推断出类是对象,从2开始,我们可以推断出类必须有类。但是为了满足3,我们需要X
和Class
之间的一些类,以便类可以拥有其他类无法访问的方法。单例类是这三个假设的必然结果。