フィッタ
このページの目的
このページで説明する部位を以下に示します。テンプレートを五つに分割したうちの二つ目の部位になります。
_fitter() メソッドは Rice クラスの初期化に関する振舞を定義します。具体的には、Rice の new 式で呼び出されるフィッタがこのメソッドによって定義されます。
このメソッドは Rtype クラスの定義で抽象メソッドとして宣言されています。したがって、Rtype 派生クラスで実装しなければいけません。
目次:
new 式(Rice)
まずは Rice の new 式について説明します。
new 式はインスタンスを生成するための式です。例えば、
fake fakeInstance = new fake();
代入記号(=)の右辺が new 式です。キーワード new で始り、クラス名が続き、引数が指定されます。Rice は、これらの情報からRtype 派生クラスのインスタンスを生成して、_fitter() メソッドを呼び出して初期化ルーチンを実行します。
第一引数 : string signature
上記の new 式から Rice は fake クラスのインスタンスを生成します。次に、インスタンスに呼び出す初期化ルーチンを決定するために、フィッタシグネチャを作成します。
フィッタシグネチャは呼び出す初期化ルーチンを区別するための名前です。_fitter() メソッドの第一引数として渡されます。
第二引数 : VirtualMachine vm
第二引数として VirtualMachine クラスのインスタンスが渡されます。これはスクリプトを実行している仮想機械です。
例外を投げる必要があるときは、この引数から取得してください。例外が発生したソースファイル名や行数などの情報がセットされた例外が取得できます。
throw vm.GetRtypeException("例外のメッセージ", "例外名"); // 補足的な情報がセットされた例外。 |
第三引数 : Queue<Rtype> argqueue
Rice は new 式を解析して引数を第三引数に格納して _fitter() メソッドに渡します。
第三引数には引数に対応する Rtype 派生クラスのインスタンスが出現順に入っています。
テンプレートの修正
_fiiter() メソッドを fake クラスのために修正します。fake クラスは文字列によるフィッタを持ちます。この他にデフォルトフィッタも実装します。
1: | public override bool _fitter(string signature, VirtualMachine vm, Queue<Rtype> argqueue) { |
2: | switch (signature) { |
3: | case TYPENAME + "()": { // new fake() -> "fake()" |
4: | return true; |
5: | } |
6: | case TYPENAME + "(" + Rstring.TYPENAME + ")": { // new fake("任意文字列") -> "fake(string)" |
7: | InternalData = (Rstring)argqueue.Dequeue(); |
8: | return true; |
9: | } |
10: | default: |
11: | return false; |
12: | } |
13: | } |
switch 文を使い適切なルーチンへ分岐させています。各 case の値はクラスの TYPENAME を合成することで作成しています。
三~五行目が引数を持たないフィッタ、デフォルトフィッタの定義です。ここでは例示のために敢てデフォルトフィッタを実装していますが fake クラスのデフォルトフィッタは true を返すだけで何もしていません。
六~九行目が文字列の引数を一つ持つフィッタの定義です。
七行目でフィッタに渡された引数を第三引数から取り出しています。フィッタシグネチャと第三引数に格納されているインスタンスはクラスと数が完全に一致します。 したがって、取得した引数を安全にキャストできます。
InternalData へ Rstring クラスの引数を直接代入していますが、Rstring クラスは C# の string へ暗黙的にキャストできるので代入できます。
それぞれの初期化ルーチンが true を返して終了していることに注意してください。true は第一引数に対応するフィッタが存在して初期化が成功したことを示します。
default: で false を返しています。false は対応するフィッタが存在しなかったことによる処理失敗を表します。false が返された場合は Rice が例外を投げます。
デフォルトフィッタ
引数のないフィッタをデフォルトフィッタと呼びます。
上記のデフォルトフィッタは例示のために実装しましたが、何もしないデフォルトフィッタは実装する必要がありません。同等のデフォルトフィッタが自動的に生成されます。
自動的に実装されたデフォルトフィッタは宣言文で返されるインスタンスと同じものを返します。
フィッタが必要無い場合
クラスにフィッタが必要無い場合は以下のように_fitter()メソッドを実装してください。
1: | public override bool _fitter(string signature, VirtualMachine vm, Queue<Rtype> argqueue) { |
2: | return false; |
3: | } |