オブジェクト名の検索

"//"(Rootオブジェクト)から始まる階層構造に含まれるオブジェクトは、グローバル変数としての性質を持っており、スクリプトの変数スコープの枠を越え、どのような位置からでも参照することができます。

ここでは、スクリプト中に記述されるオブジェクト名をインタプリタがどのように検索して、該当するオブジェクトを発見するかを詳細に説明しています。

オブジェクト検索の基点

CRSプログラムは、JavaScriptやJAVA、C++などの言語と同様にthisの概念を持っています。
オブジェクトの検索は常にthisを基点として解決されます。
基点となるthisは次のように規定されています。

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インタプリタは次のルールで検索し、解決します。


  1. 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】
}
【1】は、先の例と同様に検索に失敗します。
【2】は、for_loop.crs内にx2が検出できないため検索に失敗します。
【3】は、(D)を検索します。
var変数は、実行時ではなくコンパイル時に名前解決されインタプリタが実行する中間コードのバイナリに変換されます。
このような、スクリプトファイルに依存した名前解決は、var変数にのみ適用されます。
  1. thisの下位に位置するオブジェクト名と比較します。
  2. thisのオブジェクトが持つプロパティ名と比較します。
  3. thisのオブジェクトが持つメソッド名と比較します。
  4. thisの名前と比較します。
  5. thisの親のオブジェクト名と比較します。以降、該当するオブジェクトが見つかるまで、上位のオブジェクトを検索します。
  6. グローバル名前空間から検索します。
以上の検索で対象となるオブジェクトが検出できない場合、名前は未解決となります。
また、最初の名前を解決後、以下のルールで続くピリオドで連結されたすべての名前を解決します。
  1. 解決された名前がオブジェクト名ではない(プロパティ名、メソッド名など)の場合、検索は失敗します。
  2. ピリオドの左辺値で解決されたオブジェクトを基点として、その子オブジェクトを検索します。
  3. ピリオドの左辺値で解決されたオブジェクトを基点として、そのオブジェクトのプロパティを検索します。
  4. ピリオドの左辺値で解決されたオブジェクトを基点として、そのオブジェクトのメソッドを検索します。

特別なオブジェクト名

"//"は特別に、階層構造の頂点のオブジェクトを指す名前として利用できます。 "^"は特別に、thisの親オブジェクトを指す名前として利用できます。