Can eigenclasses be enumerated?

86 Views Asked by At

Calling ObjectSpace.each_object(Class) does not seem to return any eigenclasses. For example, when investigating Ruby metaclasses: why three when defined singleton methods?, I found that while ObjectSpace.count_objects[:T_CLASS] was getting incremented by 3 in the case of defining a new class with a class method, ObjectSpace.each_object(Class).count was only being incremented by one.

Is there any way to enumerate the eigenclasses active in the system?

1

There are 1 best solutions below

4
On

Looking at MRI C code, the function ObjectSpace.each_object tests if the object is an internal object and if it is true the object is removed from the iterator.

The test is made by the following function, which consider the classes internally flagged as singleton as an internal object:

static int
internal_object_p(VALUE obj)
{
    RVALUE *p = (RVALUE *)obj;

    if (p->as.basic.flags) {
    switch (BUILTIN_TYPE(p)) {
      case T_NONE:
      case T_ICLASS:
      case T_NODE:
      case T_ZOMBIE:
        break;
      case T_CLASS:
        if (FL_TEST(p, FL_SINGLETON)) /* Here */
          break;
      default:
        if (!p->as.basic.klass) break;
        return 0;
    }
    }
    return 1;
}

The Ruby EigenClasses are flagged as Singleton, so it will be not returned.

It is important to mention that, the singleton flag used internally by the MRI is different from the Singleton module from standard library.

If you create a class and include the Singleton module on it, it will be returned by the ObjectSpace.each_object method.