Posted 2020-12-19 10:56:17 GMT
allocate-instance Advent Calendar 2020 19日目の記事です。
以前、LW Dylan TranslatorというLispWorks上のDylanのシミュレーターのソースコードを眺めた時に、内部関数を使ってスロットをnil
でfill
していたのが印象に残っていたのですが、未束縛スロットの扱いが面倒なので、とりあえず:initform nil
しておくというコードもたまに見掛けたりもするので、そこそこ常套句なのかもしれません。
ということで、今回は、allocate-instance
でスロットのデフォルト値をnil
にしてみましょう。
(defpackage "cafc9fa3-5687-537e-839a-424c9b589974"
(:use c2cl slotted-objects))(cl:in-package "cafc9fa3-5687-537e-839a-424c9b589974")
(defclass default-to-nil-class (slotted-class)
())
(defmethod allocate-instance :around ((class default-to-nil-class) &key &allow-other-keys)
(let ((instance (call-next-method)))
(fill (instance-slots instance) nil)
instance))
これで下記のような動作になります。
(defclass foo (slotted-object)
((a :initform 'a)
b
c)
(:metaclass default-to-nil-class))(describe (make-instance 'foo))
⇒
#<foo 40203E71A3> is a foo
a a
b nil
c nil
当然ですが、明示的に設定したnil
なのか、暗黙のnil
なのか区別が付かなくなるので、その辺りは注意です。
そう考えると、取扱が面倒ではありますが未束縛値で埋めておくというのは妥当ではありますね。
■
HTML generated by 3bmd in LispWorks 7.0.0