1

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

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

我希望我没有混淆你。

再次感谢你。

4

2 回答 2

2

我将从以下示例开始:

class Foo
  def self.bar
    puts 12
  end
end

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

在 Ruby 中,类也是对象。现在这里#bar是一个单例方法Foo。当你这样做时Foo.barFoo首先在它的单例类中搜索,然后在祖先链单例类中搜索。单例类是一种幽灵类,因此它在祖先链中不可见,但它存在。Foo.ancestors它被语言设计者有意隐藏在输出中。单例方法由对象(此处为FOO)直接调用,在该对象上创建了单例(每个对象基础类)类。您不能创建单例类的实例。

这是一个证明:

Foo.singleton_class.new # can't create instance of singleton class (TypeError)

请记住,类的单例方法 say hereBar也可用于其后代类(here Foo)。因为 Bar 的元类变成了元类的Foo类,当你写的时候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>
于 2014-02-09T21:47:24.950 回答
1

对于您的第一个问题,假设 X 类包含以下内容:

class X
  def self.class_method
  end
end

然后class_method是一个实例方法X.singleton_class,可以通过运行看到

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

为了了解单例类与类层次结构的关系,我发现这样的图表很有帮助(特征类是单例类的另一个名称):

在此处输入图像描述

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

  1. 一切都是对象
  2. 每个对象都有一个类
  3. 类可以有其他类没有的方法

从1,我们可以推断出类是对象,从2,我们可以推断出类必须有类。但是为了满足 3,我们需要在和之间的某个类XClass以便类可以具有其他类无法访问的方法。那么单例类是这三个假设的必然结果。

于 2014-02-09T21:49:46.373 回答