クラスの再定義
CL-USER> (defclass foo () ((x :accessor foo-x :initform 1))) #<STANDARD-CLASS FOO> CL-USER> (defclass bar (foo) nil) #<STANDARD-CLASS BAR> CL-USER> (setq b (make-instance 'bar)) #<BAR #x1A3190F5> CL-USER> (setf (foo-x b) 10) 10 ;; y というスロットは存在しないよ! CL-USER> (slot-exists-p b 'y) NIL ;; foo クラス(barの親)を再定義 CL-USER> (defclass foo () ((x :accessor foo-x :initform 1) (y :accessor foo-y :initform 2))) ;WARNING: The generic function #<STANDARD-GENERIC-FUNCTION (SETF FOO-X)> is ; being modified, but has already been called. ;WARNING: Removing method ; #<CLOS:STANDARD-WRITER-METHOD ; (#<BUILT-IN-CLASS T> #<STANDARD-CLASS FOO>)> ; in #<STANDARD-GENERIC-FUNCTION (SETF FOO-X)> ;WARNING: DEFCLASS: Class BAR (or one of its ancestors) is being redefined, ; instances are obsolete #<STANDARD-CLASS FOO :VERSION 1> ;; さっき書き換えた値はそのまま CL-USER> (foo-x b) 10 ;; y が存在してる! CL-USER> (slot-exists-p b 'y) T CL-USER> (foo-y b) 2
なるほどー。
おかげで、システムを停止することなくクラスを書き換えたり出来る、と。
何らかの理由で*1再定義ではなく新規に定義したい場合は、(unintern 'foo)などやればいいみたい。
*1:現時点では思いつかない...