Home Notices Documents Classes Download Others Rice
Documents  >  開発  >  動的組み込みクラスの実装  >  セッタ
セッタの実装

このページの目的

このページは概要のページで述べたように、Rtemplate.csを五つに分けた三つ目の部分を詳説します。



今回説明する部分では、_setter()メソッドを定義しています。これはRtypeの定義で宣言されている抽象メソッドで、Rtypeの派生クラスで必ず実装しなければいけません。

したがって、組み込みクラスの実装では_setter()メソッドを必ず定義しなければいけません。

_setter()メソッドはクラスのインターフェースであるセッタの振舞を定義するためのメソッドです。セッタはインスタンスに値を設定するためのインターフェースであり、C#のプロパティのsetに相当します。


最初のセクションでセッタについて説明します。

_setter()メソッドで重要なのはメソッドの引数です。引数毎にセクションを設けて解説します。

最後に実装の例を示すためのセクションを設けます。

セッタとは

セッタはインスタンスに値を設定するためのインターフェースです。

セッタの振舞をfileクラスを例として示します。


file someFile = new file("c:\somewhere....");

someFile.IsReadOnly = true;


IsReadOnlyがセッタです。例に示すように代入演算子の左側に現れて値を代入することができます。このような値を代入するためのインタフェースがセッタです。例ではIsReadOnlyにtrueが代入されてsomeFileが読み出し専用のファイルになります。

Riceにおいて代入文の左辺に現れて値を代入することが出来るのは変数とセッタしかありません。したがって、ユーザが代入文の形式を使ってインスタンスの状態を変更できるようにするにはセッタを定義しなくてはなりません。


セッタが呼び出された時のRiceの振舞を説明します。

代入文の左辺にセッタが現れた場合、Riceはまず代入文の右辺の式を評価して代入する値を確定します、そしてセッタの名前と代入する値のクラス名からセッタを呼び出す名前(セッタシグネチャ)を作成します。上の例で言えば、セッタの名前がIsReadOnlyで代入値のクラス名がboolなので、セッタシグネチャ - IsReadOnly(bool) - を作成します。このセッタシグネチャと代入値を渡してsomeFileの_setter()メソッドを呼び出すことでsomeFileの状態が変更されるわけです。

第一引数 : string signature

作成されたセッタシグネチャは_setter()の第一引数であるsignatureとしてメソッドに渡されます。

セッタシグネチャの生成規則については上で説明したとおりです。セッタの名前と、代入値のクラス名を括弧で囲んだものの連結になります。

コンテナクラス - list、dictionary、stack、queue - のクラス名については注意が必要です。これらのクラスは内部に保持するクラスを指定できます。

例えば、素のlistクラスのクラス名はlistですが、stringクラスだけを保持するようにした場合のクラス名はlist{string}になります。他のコンテナクラスについても同様です。

これが、そのままセッタシグネチャに現れることに注意してください。

この様にして作成されたセッタシグネチャが_setter()の第一引数であるsignatureとしてメソッドに渡されます。

第二引数 : VirtualMachine vm

第二引数としてVirtualMachineクラスのインスタンスが渡されます。これはスクリプトが実行されている仮想機械を表します。

この引数のほぼ唯一の使用目的は例外クラスのインスタンスの取得です。もし例外を投げる必要があるときはVirtualMachineから取得してください。

例えば


throw vm.GetRtypeException("例外のメッセージ");


_setter()メソッド内から投げる例外ですので、RtypeExceptionクラス(クラス関連の例外を想定している)を用いるのが適切です。そこでGetRtypeException()でそのインスタンスを取得して投げています。

この引数は、例外についての詳細なメッセージを持たせたい場合に役に立ちます。また、例外の発生場所に近いところから例外を投げれば補足的な情報もより正確になります。補足的な情報とは例外が発生したソースファイル名や行数などの位置情報です。VirtualMachineクラスから例外を取得すれば、それらの情報は自動的に例外にセットされます。

C#としての普通の例外を投げても、それはすぐ捕捉されてUnknownExceptionクラスに変換されます。その際に補足的な情報が自動的にセットされるので、それほど神経質になる必要はありません。

第三引数 : Rtype arg

代入文の右辺を評価した結果のインスタンスがargに格納されて_setter()メソッドに渡されます。

実装の一案

signatureにセッタシグネチャが、argに実際の引数が格納されていることを利用して必要な処理を行えます。

ここではtemplateクラスのためにintクラスのセッタとstringクラスのセッタの実装例を示してみます。

1:public override bool _setter(string signature, VirtualMachine vm, Rtype arg) {
2:switch (signature) {
3:case "IntSetter(" + Rint.TYPENAME + ")": {
4:int intVal = (Rint)arg;
5:// 必要な処理があるときはここに実装する。
6:return true;
7:}
8:case "StringSetter(" + Rstring.TYPENAME + ")": {
9:string strVal = (Rstring)arg;
10:// 必要な処理があるときはここに実装する。
11:return true;
12:}
13:default:
14:return false;
15:}
16:}

この例ではswitch文を使いsignatureに格納されたセッタシグネチャを判定して条件分岐させています。各caseの値はセッタの名前とクラスのTYPENAMEを合成することで作成できます。

argには実際の引数が格納されています。argをキャストすれば必要な引数が正しく取得できます。組み込みクラスのキャストについてはマニュアルを参照するかVisual Studio のオブジェクトブラウザーで確認してくさだい。

この例では何もしていませんが、実際の組み込みクラスの実装ではcaseで分岐した後に必要な処理を行います。処理が終了したらtrueを返していることに注意してください。trueはセッタが存在し処理が無事に終了したことを示します。

default:でfalseを返しています。falseは適切なセッタが存在しなかったことによる処理失敗を表します。falseが返された場合は例外が投げられます。

セッタが無い場合の実装

クラスにセッタが必要無い場合もあります。

そのような場合は以下のように_setter()メソッドを実装してください。

1:public override bool _setter(string signature, VirtualMachine vm, Rtype arg) {
2:return false;
3:}

次のページでは

これでセッタの実装についての説明は終了です。

次のページではクラスのインターフェースであるゲッタの実装について説明します。

Next
Previous
Copyright © CookerGX All rights reserved.