Eu estava estudando sobre a metaclasse de Ruby. I ler esta resposta onde é bem descreveu o que metaclass é. É mostrado lá quando uma classe é criada, ela cria dois objetos. O que é compreensível. Um para a classe em si e outro para sua metaclasse. Mas quando estou tentando, vejo que está criando três 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
Eu estou usando Ruby - 2.5.1
.
Alguém pode me ajudar a entender esse?
Atualizar:
A referência de forma a deixar que é adicionado usando rubi-1.9.1 ou superior, tal como o método count_objects
para ObjectSpace
foi introduzido em 1.9.1. Parece que a T_CLASS
contagem sempre foi sempre 3 (tentada com ruby-1.9.3-p551
).
Então, até agora ainda é um mistério o porquê dessa resposta . Ruby sob um microscópio também diz que a contagem é 2.
ruby
ruby-1.9.3
Rafayet Monon
fonte
fonte
2
. Quando executado com IRB, a diferença é3
. O IRB parece estar fazendo algo por conta própria. Você obteve seu resultado usando o IRB? De qualquer forma, osObjectSpace
métodos de execução executados no IRB (e Pry, talvez) fornecem resultados distorcidos.--disable-jit --disable-gems --disable-did_you_mean
, obtenho menos ainda, mas a contagem é sempre consistente entre as execuções e sempre difere por 3. Estou usando o YARV 2.7.1 da Homebrew no macOS "Catalina" 10.15.4.class Test; end
a diferença na contagem é 2; quando executoclass Test; def self.t; end; end
a diferença é 3, aparentemente porque a criação do método class criaTest
a classe singleton da. No entanto, se eu executarObjectClass.each_object(Class)
antes e depois da diferença nas matrizes, é[Test]
no primeiro caso e[Test, #<Class:Test>]
no segundo.Respostas:
De https://bugs.ruby-lang.org/issues/16788 :
Modificando um pouco o código da pergunta:
Eu recebo os seguintes resultados:
Eu tentei com o Ruby 2.6 e 2.0 dentro e fora de um console (os números diferem, mas a diferença é a mesma) e o @SajibHassan com 1.9.3 (versão na qual o método
count_objects
foi introduzido). Isso significa que a diferença sempre foi 3 e que a primeira classe singleton criada não está acessível para o usuário.O livro Ruby Under a Microscope (escrito em 2012 após o lançamento do Ruby 2.1) também descreve a criação de apenas duas metaclasses, o que não corresponde ao resultado obtido.
Observe que métodos como
Module#prepend
(introduzidos no Ruby 2.0), mencionados por @ JörgWMittag nos comentários como o possível motivo para essa classe extra, usamT_ICLASS
. Verifique a confirmação na qual o método foi introduzido para obter detalhes. Eu acho queT_ICLASS
significa classe interna e, consequentemente, classes internas não devem ser visíveis para o usuário (o que faz sentido). Não sei ao certo por que algunsT_CLASS
são acessíveis ao usuário e outros não.fonte