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))
(1 b 2)) (:default-initargs a
フォーム デフォルト初期化引数リスト スロット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