7.6.6.2. Standard Method-Combination
method-combinationのstandard
は、standard-generic-function
クラスによって提供されます。 これはmethod-combinationのタイプが指定されなかった場合か、 あるいは組み込みのmethod-combinationタイプであるstandard
が指定された場合に使われます。
プライマリメソッドは有効なメソッドのメインとなる動作として定義されます。 補助メソッドは3つあるうちの1つの方法を用いて動作を変更します。 プライマリメソッドは修飾子を持ちません。
補助メソッドは、修飾子:before
, :after
, そして:around
のメソッドです。 method-combinationのstandard
は、メソッドに対して2つ以上の修飾子を許容しません。 もしメソッド定義で複数の修飾子をもつメソッドを定義した場合は、エラーが発せられます。
before
メソッドは、ただひとつの修飾子として:before
キーワードを持ちます。 before
メソッドは、プライマリメソッドの前に実行されるコードを定義します。
after
メソッドは、ただひとつの修飾子として:after
キーワードを持ちます。 after
メソッドは、プライマリメソッドの後に実行されるコードを定義します。
around
メソッドは、ただひとつの修飾子として:around
キーワードを持ちます。 around
メソッドは、他の適用可能なメソッドの代わりとして実行されますが、 いくつかのシャドウされたメソッドを(call-next-method
経由で)呼び出すコードを、 明に含むことができます。
method-combinationのstandard
の意味を次に示します。
もしaround
メソッドが存在する場合は、最も特定的なaround
メソッドが呼ばれます。 これはジェネリック関数に対して1つか複数の返却値を提供します。
around
メソッドのコード内では、次のメソッドを呼ぶためのcall-next-method
が使用できます。 次のメソッドから戻ったとき、around
メソッドは返却された値に基づいて、 さらにコードを実行することができます。 もしcall-next-method
を使用したときに呼び出せる適用可能なメソッドが存在しなかった場合は、 ジェネリック関数no-next-method
が呼び出されます。 関数next-method-p
は、次のメソッドが存在するかどうかを決定するために使われます。
もしaround
メソッドがcall-next-method
を実行したとき、 次の特定的なaround
メソッドが適用可能であれば呼び出されます。 もしaround
メソッドが存在しないか、 あるいは最も特定的ではないaround
メソッドによってcall-next-method
が呼び出された場合は、 次に示すものとして他のメソッドが呼び出されます。
全てのbefore
メソッドがmost-specific-first
の順番で呼ばれます。 これらの返却値は無視されます。 もしbefore
メソッド内でcall-next-method
が使用された場合は、エラーが発せられます。
最も特定的なプライマリメソッドが呼び出されます。 プライマリメソッドのコード内では、 次の特定的なプライマリメソッドを呼び出すためのcall-next-method
が使用できます。 メソッドから戻ったとき、以前のプライマリメソッドは返却された値に基づいて、 さらにコードを実行することができます。 もしcall-next-method
を使用したときに、呼び出せる適用可能なメソッドが存在しなかった場合は、 ジェネリック関数no-next-method
が呼び出されます。 関数next-method-p
は、次のメソッドが存在するかどうかを決定するために使われます。 もしcall-next-method
が使われなかった場合は、最も特定的なプライマリメソッドだけが呼び出されます。
全てのafter
メソッドがmost-specific-last
の順番で呼ばれます。 これらの返却値は無視されます。 もしafter
メソッド内でcall-next-method
が使用された場合は、エラーが発せられます。
もしaround
メソッドが呼び出されなかった場合は、 最も特定的なプライマリメソッドが、 1つか複数の値をジェネリック関数の返却値として返却します。 最も特定的ではないaround
メソッドから call-next-method
の呼び出しによって返却される1つか複数の返却値は、 最も特定的なプライマリメソッドの返却値となります。
method-combinationのstandard
では、適用可能なメソッドが存在しても、 適用可能なプライマリメソッドが存在しなかった場合はエラーが発せられます。
before
メソッドはmost-specific-first
順にて実行され、 after
メソッドはleast-specific-first
順に実行されます。 この設計の違いの根拠を、例として次のように示します。 クラスC1
がスーパークラスであるC2
の動作を、 before
メソッドとafter
メソッドに追加することで変更することを考えます。 クラスC2
の振る舞いがC2
のメソッドとして直接定義するか、 あるいはスーパクラスを継承によるものかに関わらず、 クラスC1
のインスタンスによって呼び出されるメソッドの相対的な順番には影響しません。 クラスC1
のbefore
メソッドは、クラスC2
の全てのメソッドの前に実行されます。 クラスC1
のafter
メソッドは、クラスC2
の全てのメソッドの後に実行されます。
対称的に、全てのaround
メソッドが実行されるのは、他のメソッドが実行される前です。 このように最も遠いaround
メソッドは、最も特定的なプライマリメソッドの前に実行されます。
もしプライマリメソッドのみが宣言されており、 さらにcall-next-method
が使用されなかった場合は、 最も特定的なメソッドのみが実行されます。 つまり最も特定的なメソッドが他の一般的なメソッドをシャドウしたということです。