首页 > 解决方案 > 何时在 Ruby 中分配单例类?

问题描述

在 MRI Ruby 中,何时分配单例类?

我刚刚发现单例类也可以有自己的单例类。

因此,可以调用

Object.singleton_class.singleton_class.singleton_class.singleton_class...

直到时间本身的尽头。显然,默认情况下,虚拟机不会分配所有这些单例类。

Ruby 虚拟机究竟何时分配单例类?如果我没有在其上定义任何方法并且不调用,那么对象是否有一个单例类Object#singleton_class

标签: rubysingleton

解决方案


从 Ruby 程序的角度来看,每个对象总是有一个单例类。包括班级。包括单例类。

然而,正如您所猜测的,一些 Ruby 实现通过不预先分配所有单例类来优化这一点。

这是 YARV 所做的(据我所知):

  1. 单例类是懒惰分配的。它们仅在您尝试访问它、打开它或在其中定义方法或常量或变量时创建。这是内存优化
  2. 但是,这种惰性分配有一些开销。由于模块和类通常具有单例方法,对于类和模块来说,这是不同的:对于类和模块,YARV 在(类/模块)对象被实例化后立即创建一个单例类。这是一个速度优化
  3. 当然,正如您在问题中所说,这会导致无限递归。因此,#2 仅适用于“普通”类,而不适用于单例类。

所以:单例类被懒惰地实例化。类和模块除外。异常中的异常是单例类。

但是,让我重复一下我在开头写的内容:这是 YARV 的私有内部实现细节。其他 Ruby 实现的行为可能相同,也可能不同。

Ruby中,每个对象都存在一个单例类,包括单例类。


推荐阅读