类如何调用在单例类上定义的类方法?

时间:2014-02-09 21:38:48

标签: ruby singleton-methods

我继续研究Ruby,另一个问题发生在我身上。我知道当我们在类上定义一个类方法时,它创建了一个单例类来获取该方法的定义,从那时起,该方法就是该单例类的实例方法(我从测试中得到了这个结论,但是我可能错了,所以请随意纠正我。)

我的问题是,如果在单例类上将方法定义为该类的实例方法,我如何使用X.classMethod在类X上调用类方法(我不知道我该怎么做。是怎么回事。)它让我更加困惑,因为我注意到(运行一些测试)类的单例类甚至与它来自的类没有层次关系,所以,如何将类方法调用解析为单例类?更确切地说:类如何在单例类上调用方法,该方法是一个实例方法,没有任何实例。

我希望我没有让你感到困惑。

再次感谢你。

2 个答案:

答案 0 :(得分:2)

我将从下面的例子开始:

class Foo
  def self.bar
    puts 12
  end
end

Foo.singleton_methods # => [:bar]
Foo.ancestors # => [Foo, Object, Kernel, BasicObject]

在Ruby类中也是对象。现在,#barFoo的单例方法。当您执行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_methodX.singleton_class的实例方法,您可以通过运行

看到
X.singleton_class.instance_methods(false)
# ==> [:class_method]

要了解单例类如何与类层次结构相关,我发现这样的图表很有用(eigenclass是singleton类的另一个名称):

enter image description here

在那个图之后,我认为它有点复杂,但是使用逻辑,似乎更有必要,假设以下假设成立:

  1. 一切都是对象
  2. 每个对象都有一个类
  3. 类可以包含其他类没有的方法
  4. 从1开始,我们可以推断出类是对象,从2开始,我们可以推断出类必须有类。但是为了满足3,我们需要XClass之间的一些类,以便类可以拥有其他类无法访问的方法。单例类是这三个假设的必然结果。