オブジェクト名の検索¶
"//"(Rootオブジェクト)から始まる階層構造に含まれるオブジェクトは、グローバル変数としての性質を持っており、スクリプトの変数スコープの枠を越え、どのような位置からでも参照することができます。
ここでは、スクリプト中に記述されるオブジェクト名をインタプリタがどのように検索して、該当するオブジェクトを発見するかを詳細に説明しています。
オブジェクト検索の基点¶
Biz/Browser起動直後のthis
"//"オブジェクトがthisとなります。
オブジェクト生成のブロック
ブロックのオブジェクトがthisとなります。
Form Form1 {
X = 10; 【1】
Y = 10; 【2】
Button Button1 {
X = 10; 【3】
Y = 20; 【4】
String str1 {
value = "abc"; 【5】
}
}
}
【1】〜【2】: thisはForm1です
【3】〜【4】: thisはButton1です
【5】: thisはstr1です
イベントハンドラのthis
イベントハンドラを持つオブジェクトがthisとなります
ユーザ定義関数のthis
関数を所有するオブジェクトがthisとなります
オブジェクトの検索¶
オブジェクトの検索はthisを基点として "."(ピリオド)で名前を連結して表現します。
名前の大文字小文字は区別されません。
Form1.Button1.str1 = "xyz";
このような名前をピリオドで連結したオブジェクト検索式をCRSインタプリタは次のルールで検索し、解決します。
- var変数をプログラムブロックの内側から外側に向けて検索します。
検索は、実行時のコンテキストが途絶えるか、現在のスクリプトファイル内のブロックが終わるところまで行われます。
実行時のコンテキストの切れ目
Button B1 {
var x1 = 10; (A)
X = 10;
:
function onTouch(e) {
:
var x2 = 20; (B)
var x3 = 20; (C)
for ( … ) {
var x3 = 30; (D)
x1 = 1; 【1】
x2 = 2; 【2】
x3 = 3; 【3】
}
}
}
【1】は、Functionにより実行コンテキストが異なるので(A)のx1を検出できず検索は失敗します。 【2】は、(B)のx2が検索されます。 【3】は、(C)と(D)で定義されるx3の内、先に検出される(D)が検索されます。
現在のスクリプトファイル内の検索
上記の例と同じ構造を、getメソッドを使い2つのスクリプトファイルに分けた場合、検索式の解決結果が異なります。
Button B1 {
var x1 = 10; (A)
X = 10;
:
function onTouch(e) {
var x2 = 20; (B)
var x3 = 20; (C)
get("for_loop.crs");
}
}
----- for_loop.crs -----
for ( … ) {
var x3 = 30; (D)
x1 = 1; 【1】
x2 = 2; 【2】
x3 = 3; 【3】
}
- thisの下位に位置するオブジェクト名と比較します。
- thisのオブジェクトが持つプロパティ名と比較します。
- thisのオブジェクトが持つメソッド名と比較します。
- thisの名前と比較します。
- thisの親のオブジェクト名と比較します。以降、該当するオブジェクトが見つかるまで、上位のオブジェクトを検索します。
- グローバル名前空間から検索します。
- 解決された名前がオブジェクト名ではない(プロパティ名、メソッド名など)の場合、検索は失敗します。
- ピリオドの左辺値で解決されたオブジェクトを基点として、その子オブジェクトを検索します。
- ピリオドの左辺値で解決されたオブジェクトを基点として、そのオブジェクトのプロパティを検索します。
- ピリオドの左辺値で解決されたオブジェクトを基点として、そのオブジェクトのメソッドを検索します。
特別なオブジェクト名¶
"//"は特別に、階層構造の頂点のオブジェクトを指す名前として利用できます。 "^"は特別に、thisの親オブジェクトを指す名前として利用できます。