Estaba estudiando sobre la metaclase de Ruby. Yo leí esta respuesta en la que se describe muy bien lo que es metaclase. Se muestra allí cuando se crea una clase, creará dos objetos. Lo cual es comprensible. Uno para la clase en sí y otro para su metaclase. Pero cuando lo intento, veo que está creando tres objetos.
puts "Before Class Creation object count - #{ObjectSpace.count_objects[:T_CLASS]}"
class Test
def self.foo # test_singleton
p 'Printed from method #foo'
end
def bar # test
p 'Printed from method #bar'
end
end
puts "After Class Creation object count - #{ObjectSpace.count_objects[:T_CLASS]}"
###############
Before Class Creation object count - 949
After Class Creation object count - 952
Estoy usando Ruby - 2.5.1
.
¿Alguien puede ayudarme a entender esto?
Actualizar:
La referencia SO Post que añadí está utilizando ruby-1.9.1 o mayor, como el método count_objects
para ObjectSpace
se introdujo en 1.9.1. Parece que el T_CLASS
conteo siempre ha sido 3 (probado con ruby-1.9.3-p551
).
Entonces, hasta ahora sigue siendo un misterio por qué esta respuesta . Ruby bajo un microscopio también dice que el recuento es 2.
ruby
ruby-1.9.3
Rafayet Monon
fuente
fuente
2
. Cuando se ejecuta con IRB la diferencia es3
. IRB parece estar haciendo algo por su cuenta. ¿Obtuviste tu resultado usando IRB? En cualquier caso, losObjectSpace
métodos de ejecución ejecutados dentro de IRB (y Pry, tal vez) dan resultados distorsionados.--disable-jit --disable-gems --disable-did_you_mean
, obtengo aún menos, pero el conteo siempre es consistente en las ejecuciones y siempre difiere según 3. Estoy usando YARV 2.7.1 de Homebrew en macOS "Catalina" 10.15.4.class Test; end
la diferencia en conteo es 2; cuando ejecutoclass Test; def self.t; end; end
la diferencia es 3, aparentemente porque crear el método de clase creaTest
la clase singleton. Sin embargo, si ejecutoObjectClass.each_object(Class)
antes y después, la diferencia en las matrices es[Test]
en el primer caso y[Test, #<Class:Test>]
en el segundo.Respuestas:
De https://bugs.ruby-lang.org/issues/16788 :
Modificando un poco el código de la pregunta:
Obtengo los siguientes resultados:
Lo probé con Ruby 2.6 y 2.0 dentro y fuera de una consola (los números difieren pero la diferencia es la misma) y @SajibHassan con 1.9.3 (versión en la que
count_objects
se introdujo el método ). Esto significa que la diferencia siempre ha sido 3 y que la primera clase singleton creada no es accesible para el usuario.El libro Ruby Under a Microscope (escrito en 2012 después del lanzamiento de Ruby 2.1) también describe la creación de solo dos metaclases, que no coinciden con el resultado que obtenemos.
Tenga en cuenta que los métodos como
Module#prepend
(introducido en Ruby 2.0), que fue mencionado por @ JörgWMittag en los comentarios como la posible razón de esta clase adicional, useT_ICLASS
. Verifique el commit en el que se introdujo el método para más detalles. Supongo que esoT_ICLASS
significa clase interna y, en consecuencia, las clases internas no deberían ser visibles para el usuario (lo cual tiene sentido). Sin embargo, no estoy seguro de por qué algunosT_CLASS
son accesibles para el usuario y otros no.fuente