2016-08-07 10 views
8

これは私には何度も起こります。私はクラスを定義し、それがfuncallableか、Gtkウィジェットクラスであることを忘れてしまい、メタクラスを記述する必要があります。しかし、それが定義されると、SBCLは(たとえこのクラスのインスタンスがなくても)私にメタクラスを変更させません。例えば、クラスのメタクラスを変更するには

(defclass foo() 
    ((slot-a))) 

を評価して、メタクラスを追加し、再評価:エラーで

(defclass foo() 
    ((slot-a)) 
    (:metaclass gobject:gobject-class)) 

結果:

Cannot CHANGE-CLASS objects into CLASS metaobjects. 
    [Condition of type SB-PCL::METAOBJECT-INITIALIZATION-VIOLATION] 
See also: 
    The Art of the Metaobject Protocol, CLASS [:initialization] 

残念ながら、私はアートのコピーを持っていませんそれが何であるかを確認するためにメタオブジェクトプロトコルの今のところ私が把握できる唯一の方法は、lispを再起動することです。これはかなり混乱することがあります。

すぐにエラーが発生するので、定義したクラスを完全に削除しても構いません。質問:

  • クラスのインスタンスを作成した場合、それらを無効にしてGCedを取得する方法はありますか?
  • クラスを削除するには?機能のためにはfmakunboundのようなものです。私は本を​​読んで、あなたがオンラインでいくつかの情報を見つけることができるお勧めしていても

答えて

9

Unfortunately I don't have a copy of The Art of the Metaobject Protocol to check what it says.

。例えば、ENSURE-CLASS-USING-CLASSを参照してください。あなたは空想スライムインスペクタを使用することができ、

(setf (find-class 'foo) nil) 

をまたは:

How to remove the class?

あなたは(SETF FIND-CLASS)を使用することができます。クラス名を指してslime-inspect-defintionに電話します。その後、名前が表示されます。選択すると、クラスの名前を示すシンボルが検査されます。次に、あなたのような何かを見ることができます:

It names the class FOO [remove] 

提供FOO名前だけクラスを、あなたは大きなハンマーを使用することができます:いいえ、唯一のGCは、グローバルな視野を持って

(unintern 'foo) 

If I have created instances of the class, is there a way to find them to nullify them and get them GCed?

をし、実用的な理由から、誰が特定のオブジェクトを参照しているかについての後方参照は一般的にはありません(および方法)。 クラスを格納する独自の(弱い)ハッシュテーブルを導入しない限り、クラスのすべてのインスタンスのグローバルレコードはありません。しかし、すべてのインスタンスの記録を残しておけば、CHANGE-CLASSとすることができます。たとえば、ユーザーが定義:

(defclass garbage()()) 

を...あなたのオブジェクト内の任意の以前に開催された参照が解放され、GCは、参照オブジェクトのインスタンスを配置する機会を持っています。そして、別のオブジェクトが 'garbage'のインスタンスを参照すると、それを更新することができます。 'garbage'を使用する代わりに、古いクラスのインスタンスを新しいクラスに変更することもできます(名前は同じですが、クラスオブジェクトは異なります)。 また、CHANGE-CLASSは汎用関数であることに注意してください。


。実装では、ヒープウォーカーが提供されます。例えばHeap walkers in Allegro CLを参照してください。

関連する問題