セッタ
このページの目的
このページで説明する部位を以下に示します。テンプレートを五つに分割したうちの三つ目の部位になります。
_setter() メソッドは Rice クラスのインターフェースであるセッタの振舞を定義します。セッタはインスタンスの内部状態を変更するためのインターフェースです。
このメソッドは Rtype クラスの定義で抽象メソッドとして宣言されています。したがって、Rtype 派生クラスで実装しなければいけません。
fake クラスにセッタ Value を定義することによって、セッタの定義方法を説明します。
目次:
セッタとは
セッタはインスタンスの状態を変更するためのインターフェースです。その振舞は以下のようになるでしょう。
fake fakeInstance = new fake();
fakeInstance.Value = "代入文字列";
Value がセッタです。代入演算子の左側に現れたセッタには値を代入することができます。代入により fakeInstance の内部データが "代入文字列" に変更されます。
Rice において代入文の左辺に現れて値を代入することが出来る要素は、フィールド、変数、セッタです。
フィールド、変数への代入はインスタンス自体の変更です。インスタンスの内部状態を変更できるのはセッタだけです。
第一引数 : string signature
代入文の左辺にセッタが現れた場合、Rice は代入文の右辺の式を評価して代入値を確定します。そして、セッタを呼び出す名前であるセッタシグネチャを作成します。
セッタシグネチャは _setter() メソッドの第一引数として渡されます。
第二引数 : VirtualMachine vm
第二引数として VirtualMachine クラスのインスタンスが渡されます。これはスクリプトを実行している仮想機械です。
例外を投げる必要があるときは、この引数から取得してください。例外が発生したソースファイル名や行数などの情報がセットされた例外が取得できます。
throw vm.GetRtypeException("例外のメッセージ", "例外名"); // 補足的な情報がセットされた例外。 |
第三引数 : Rtype arg
代入文の右辺を評価した結果が第三引数に格納されて _setter() メソッドに渡されます。
テンプレートの修正
_setter() メソッドを fake クラスのために修正します。
1: | public override bool _setter(string signature, VirtualMachine vm, Rtype arg) { |
2: | switch (signature) { |
3: | case "Value(" + Rstring.TYPENAME + ")": { // "Value(string)" |
4: | InternalData = (Rstring)arg; |
5: | return true; |
6: | } |
7: | case "Value(" + TYPENAME + ")": { // "Value(fake)" |
8: | fake f = (Rfake)arg; |
9: | InternalData = f.InternalData; |
10: | return true; |
11: | } |
12: | default: |
13: | return false; |
14: | } |
15: | } |
switch 文を使い適切なルーチンへ分岐させています。各 case の値はクラスの TYPENAME を合成することで作成しています。
三~六行目で Value セッタを定義しています。string クラスを代入することで内部データを変更します。
フィッタの説明で述べたように、Rice の string(Rstring) クラスは C# の string へ暗黙的にキャストできます。したがって、InternalData へ Rstring クラスの引数を直接代入できます。
七~十一行目で Value セッタを定義しています。こちらの Value セッタは fake クラスの内部データを代入することで内部データを変更します。
Rfake クラスの定義の中なので、Rfake の private メンバにアクセスできます。そこで、InternalData へ f (Rfake) の InternalData を直接代入しています。
どちらのセッタも代入値を第三引数から取り出しています。セッタシグネチャと第三引数はクラスが絶対に一致します。したがって、取り出した引数は安全にキャストすることが出来ます。
それぞれのセッタルーチンが true を返して終了していることに注意してください。true は第一引数に対応するセッタが存在して処理が成功したことを示します。
default: で false を返しています。false はセッタが存在しなかったことによる処理失敗を表します。false が返された場合は Rice が例外を投げます。
オーバーロード
上記のコードのセッタ名が同じであることに注意してください。
セッタ名は同じですが、セッタシグネチャは "Value(string)" と "Value(fake)" で異なります。つまり、セッタ名が同じでも適切なルーチンを呼び出すことができます。
Rice では、代入値が異なるならば同じ名前のセッタを定義できます。これをセッタのオーバーロードといいます。
セッタが無い場合の実装
クラスにセッタが必要無い場合は、以下のように _setter() メソッドを実装してください。
1: | public override bool _setter(string signature, VirtualMachine vm, Rtype arg) { |
2: | return false; |
3: | } |