7.1.4. 初期化引数の規則
スロットオプションの:initargは、スロット対して複数定義されるかもしれません。
もし初期化引数に複数の定義がされるかもしれないときには、 下記に示すルールが適応されます。
もし同じ初期化引数の名前が :initargスロットオプションに複数現れた場合は、 初期化引数は複数のスロットを初期化できます。
初期化引数の名前は、複数の初期化メソッドのラムダリストに現れます。
初期化引数の名前は、 スロットオプションの:initargと、 初期化メソッドのラムダリストの両方に現れます。
もしmake-instanceに与えられた引数が、 同じスロットを初期化するような複数の初期化引数であった場合、 さらに初期化引数が違った名前であったときは、 初期化引数リストの 最も左の初期化引数の値が採用されます。
もし複数の違った初期化引数が同じスロットを初期化する場合、 さらにスロットはデフォルト値を持っており、 make-instanceの引数には明示的に指定されていなかったときは、 初期化引数は最も特定的な クラスのクラスオプション:default-initargsに現れる値が採用されます。 もしひとつの:default-initargsクラスオプションが、 複数の初期化引数により同じスロットを初期化する場合、 さらにmake-instanceの引数には明示的に指定がなかったときは、 クラスオプション:default-initargsの最も左側の値が採用され、 残りのデフォルト値フォームの値は無視されます。
make-instanceの引数として明示的に与えられた初期化引数は、 デフォルト初期化引数の左側に現れます。 例えば、クラスC1とC2が違うスロットに対して デフォルト初期化引数の値を与えた場合を考えます。 C1はC2よりも特定的であるとします。 C1によって提供されたデフォルト初期化引数は、 デフォルト初期化引数リストにおいては、 C2によって提供されたのデフォルト初期化引数の左側に位置します。 もし単一のクラスオプション:default-initargsが、 2つの違ったスロットに対して初期化引数の値が与えられた場合、 クラスオプション:default-initargsの最も左に位置する初期化引数が、 デフォルト初期化引数リストの最も左側に現れます。
もしスロットが:initformフォームと:initargスロットオプションの両方を持っており、 さらに初期化引数が :default-initargsによるデフォルト値により与えられているか、 あるいはmake-instanceの引数により与えられていた場合、 :initformフォームは使われませんし評価もされません。
上記の規則の例を示します。
(defclass q () ((x :initarg a)))
(defclass r (q) ((x :initarg b))
(:default-initargs a 1 b 2))フォーム デフォルト初期化引数リスト スロットXの値
----------
(make-instance 'r) (a 1 b 2) 1
(make-instance 'r 'a 3) (a 3 b 2) 3
(make-instance 'r 'b 4) (b 4 a 1) 4
(make-instance 'r 'a 1 'a 2) (a 1 a 2 b 2) 1