Ich habe über Rubys Metaklasse studiert. Ich habe diese Antwort gelesen, in der gut beschrieben ist, was Metaklasse ist. Es wird dort angezeigt, wenn eine Klasse erstellt wird, werden zwei Objekte erstellt. Welches ist verständlich. Eine für die Klasse selbst und eine für die Metaklasse. Aber wenn ich es selbst versuche, sehe ich, dass es drei Objekte schafft.
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
Ich benutze Ruby - 2.5.1
.
Kann mir jemand helfen, diesen zu verstehen?
Aktualisieren:
Der von mir hinzugefügte SO-Referenzbeitrag verwendet Ruby-1.9.1 oder höher, da die Methode count_objects
für ObjectSpace
in 1.9.1 eingeführt wurde. Es scheint, dass die T_CLASS
Zählung immer 3 war (versucht mit ruby-1.9.3-p551
).
Bis jetzt ist es immer noch ein Rätsel, warum diese Antwort . Ruby unter dem Mikroskop sagt auch, dass die Anzahl 2 ist.
quelle
2
. Bei Ausführung mit IRB beträgt der Unterschied3
. IRB scheint etwas alleine zu machen. Haben Sie Ihr Ergebnis mit IRB erhalten? In jedem Fall führen die Ausführung vonObjectSpace
Methoden, die innerhalb von IRB (und möglicherweise Pry) ausgeführt werden, zu verzerrten Ergebnissen.--disable-jit --disable-gems --disable-did_you_mean
, bekomme ich noch weniger, aber die Anzahl ist über die Läufe hinweg immer konsistent und unterscheidet sich immer um 3. Ich verwende YARV 2.7.1 von Homebrew unter macOS "Catalina" 10.15.4.class Test; end
beträgt der Unterschied in der Anzahl 2; Wenn ichclass Test; def self.t; end; end
den Unterschied ausführe, beträgt er 3, anscheinend weil beim Erstellen der Klassenmethode dieTest
Singleton-Klasse erstellt wird. Wenn ich jedochObjectClass.each_object(Class)
vor und nach dem Unterschied in den Arrays laufe, ist dies[Test]
im ersten und[Test, #<Class:Test>]
im zweiten Fall der Fall .Antworten:
Von https://bugs.ruby-lang.org/issues/16788 :
Ändern Sie den Fragencode ein wenig:
Ich erhalte folgende Ergebnisse:
Ich habe es mit Ruby 2.6 und 2.0 sowohl innerhalb als auch außerhalb einer Konsole versucht (die Zahlen unterscheiden sich, aber der Unterschied ist der gleiche) und @SajibHassan mit 1.9.3 (Version, in der die Methode
count_objects
eingeführt wurde). Dies bedeutet, dass der Unterschied immer 3 war und dass die erste erstellte Singleton-Klasse für den Benutzer nicht zugänglich ist.Das Buch Ruby Under a Microscope (geschrieben 2012 nach der Veröffentlichung von Ruby 2.1) beschreibt auch die Erstellung von nur zwei Metaklassen, die nicht mit dem Ergebnis übereinstimmen, das wir erhalten.
Beachten Sie, dass Methoden wie
Module#prepend
(eingeführt in Ruby 2.0), die von @ JörgWMittag in den Kommentaren als möglicher Grund für diese zusätzliche Klasse erwähnt wurden, verwendet werdenT_ICLASS
. Überprüfen Sie das Commit, in dem die Methode eingeführt wurde, auf Details. Ich denke, dasT_ICLASS
steht für interne Klasse und folglich sollten interne Klassen für den Benutzer nicht sichtbar sein (was Sinn macht). Ich bin mir jedoch nicht sicher, warum einigeT_CLASS
für den Benutzer zugänglich sind und andere nicht.quelle