So ändern Sie die Metaklasse der Klasse

8

Das passiert mir immer wieder: Ich definiere die Klasse und vergesse, dass ich es funcallable wollte oder es ist, sagen wir, Gtk-Widget-Klasse, also muss die Metaklasse angegeben werden. Sobald es jedoch definiert ist, lässt SBCL mich die Metaklasse nicht ändern (auch wenn es keine Instanz dieser Klasse gibt). Zum Beispiel die Auswertung von

%Vor%

und dann eine Metaklasse hinzufügen und neu auswerten:

%Vor%

führt zu einem Fehler:

%Vor%

Leider habe ich keine Kopie von The Art of the Metaobject Protocol, um zu überprüfen, was es sagt. Im Moment ist der einzige Weg, wie ich herausfinden konnte, Lisp zu starten, was ziemlich störend sein kann.

Da ich den Fehler früh genug erkenne, macht es mir nichts aus, die definierte Klasse komplett zu entfernen, indem ich sie entferne. Fragen:

  • Wenn ich Instanzen der Klasse erstellt habe, gibt es eine Möglichkeit, sie zu finden, um sie zu annullieren und ihnen GCed zu geben?
  • Wie entferne ich die Klasse? So etwas wie fmakunbound für Funktionen.
mobiuseng 07.08.2016, 07:27
quelle

1 Antwort

9
  

Leider habe ich keine Kopie von The Art of the Metaobject Protocol, um zu überprüfen, was es sagt.

Obwohl ich Ihnen das Lesen des Buches empfehle, können Sie einige Informationen online finden. Siehe zum Beispiel ENSURE-CLASS-USING-CLASS .

  

Wie entferne ich die Klasse?

Sie können (SETF FIND-CLASS) verwenden:

%Vor%

Oder Sie können den schicken Schleiminspektor benutzen. Sie rufen slime-inspect-defintion auf, während Sie den Namen der Klasse anzeigen. Dann sehen Sie den Namen. Wenn Sie es auswählen, überprüfen Sie das Symbol, das Ihre Klasse benennt. Dann können Sie etwas wie sehen:

%Vor%

Sofern FOO nur eine Klasse benennt, können Sie den größeren Hammer verwenden:

%Vor%
  

Wenn ich Instanzen der Klasse erstellt habe, gibt es eine Möglichkeit, sie zu finden, um sie zu annullieren und sie GCed zu erhalten?

Nein, nur der GC hat die globale Ansicht, und aus praktischen Gründen behält er im Allgemeinen keine Rückwärtsreferenzen darüber, wer auf ein bestimmtes Objekt (und wie) verweist 1 . Es gibt keine globale Aufzeichnung aller Instanzen einer Klasse, es sei denn, Sie führen Ihre eigene (schwache) Hash-Tabelle ein, um sie zu speichern. Wenn Sie jedoch alle Ihre Instanzen aufgezeichnet haben, können Sie sie CHANGE-CLASS verwenden. Zum Beispiel definieren Sie:

%Vor%

... jeder zuvor gespeicherte Verweis in Ihrem Objekt wird freigegeben und der GC hat die Möglichkeit, Objekte zu löschen, auf die Ihre Instanzen verweisen. Und wenn ein anderes Objekt auf eine Instanz von 'Müll' verweist, können Sie es aktualisieren. Anstatt "Müll" zu verwenden, könnten Sie wahrscheinlich Instanzen alter Klassen in Ihre neue Klasse ändern (der Name ist derselbe, aber das Klassenobjekt ist anders). Beachten Sie auch, dass CHANGE-CLASS eine generische Funktion ist.

1 Implementierungen könnten Heap Walker bieten. Siehe zum Beispiel Haufen Wanderer in Allegro CL .

>     
coredump 07.08.2016, 08:00
quelle

Tags und Links