Можно ли перечислить собственные классы?
Призвание ObjectSpace.each_object(Class)
не возвращает никаких собственных классов. Например, при исследовании метаклассов Ruby: почему три, когда определены одноэлементные методы? Я обнаружил, что в то время как ObjectSpace.count_objects[:T_CLASS]
увеличивался на 3 в случае определения нового класса с помощью метода класса, ObjectSpace.each_object(Class).count
увеличивается только на единицу.
Есть ли способ перечислить собственные классы, активные в системе?
1 ответ
Глядя на код МРТ С, функция ObjectSpace.each_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;
}
Рубиновые EigenClasses помечены как Singleton, поэтому они не будут возвращены.
Важно отметить, что флаг singleton, используемый внутри MRI, отличается от модуля Singleton стандартной библиотеки.
Если вы создадите класс и включите в него модуль Singleton, он будет возвращен ObjectSpace.each_object
метод.