Home   Single Page

zscriptの中で定義された変数とファンクション

コードを実行するに加えて、以下のように記述することで、変数と要素をzscriptメソッドの中で直接定義することができます。

<window id="A>
    <zscript>    
        Object myvar = new LinkedList();        
        void myfunc() {        
            ...            
        }        
    </zscript>    
    ...    
    <button label="add" onClick="myvar.add(some)"/>    
    <button label="some" onClick="myfunc()"/>    
</window>

zscriptの中で定義された変数とメソッドはスクリプト言語のインタプリタの中に保存されています。

zscriptとEL表記

ネーム空間[25]のように、zscriptの中で定義された変数をEL表記は参照できます。

<window>
    <zscript>    
    String var = "abc";    
    self.setVariable("var2", "xyz", true);    
    </zscript>    
    ${var} ${var2}    
</window>

上記は以下と同様です。is
equivalent to

<window>
abc xyz
</window>

zscriptの中で定義された変数はネーム空間で定義されたものより優先度が高いです。

<window>
    <zscript>    
    String var = "abc";    
    self.setVariable("var", "xyz", true);    
    </zscript>    
    ${var}    
</window>

上記は以下と同様です。

<window>
abc
</window>

以下の例のようにコンポーネントを宣言すると混乱を招くことがあります。

<window>
    <zscript>    
    String var = "abc";    
    </zscript>    
    <label id="var" value="A label"/>    
    ${var.value} <!-- Wrong! var is "abc", not the label -->    
</window>

混乱を避けるために、いくつかの名付け方式を使うことをお勧めします。たとえば、インタプリタ変数にはプレフィックスzs_をつけます。

加えて、できるだけローカル変数を使いましょう。ローカル変数はクラスの名前とともに定義され、zscriptコードの特定の範囲内のみに有効です。

<zscript>
Date now = new Date();
</zscript>

さらに、以下のように括弧でくくることでローカル変数をEL表記が参照できないように設定できます。

<zscript>
{ //create a new logic scope
    String var = "abc"; //visible only inside of the enclosing curly brace    
}
</zscript>

多領域(マルチ・スコープ)インタプリタ

定義することによって、インタプリタはひとつの領域を持つか、変数とメソッドを保存する論理領域を持つことができます。区別するために、それぞれ、シングル領域と多領域インタプリタと呼びます。

Javaインタプリタ(BeamShell)は代表的な多領域インタプリタ[26]で、それぞれのIDスペースに独立のインタプリタ領域を作ります。例えば、以下の例で二つの論理領域はそれぞれウィンドウAとBのために確保されます。そうして、var2はウィンドウBのみに有効で、var1はAとBの両方のウィンドウに有効です。

<window id="A">
    <zscript>var1 = "abc";</zscript>    
    <window id="B">    
        <zscript>var2 = "def";</zscript>        
    </window>    
</window>
Javaインタプリタ(BeanShell)

Javaインタプリタ(BeanShell)を使って、以下のようにクラスの名前を定義することで一番近いIDスペースの論理領域(つまり、ウィンドウ)にローカルインタプリタ変数を宣言することができます。

<window id="A">
    <window id="B">    
        <zscript>        
    String b = "local to window B";    
        </zscript>        
    </window>    
</window>

以下はabcとdefを作成するより、洗練された例です。

<window id="A">
    <zscript>    
    var1 = var2 = "abc";    
    </zscript>    
    <window id="B">    
        <zscript>        
    Object var1 = "123";    
    var2 = "def";    
    var3 = "xyz";    
        </zscript>        
    </window>    
    ${var1} ${var2} ${var3}    
</window>

オブジェクトvar1=123は、クラス名とオブジェクトが指定されているので、ローカル変数をウィンドウBに定義しています。一方、オブジェクト var2 = defはインタプリタに、現領域、又は上層領域(親など)内でvar2と定義された変数を参照させます。var2はウィンドウA中で定義されていて、変数 はオーバーライドされています。var3=xyzの場合では、ウィンドウAがvar3と呼ばれる変数を定義していないので、ウィンドウBにローカル変数が 指定されています。

単領域インタプリタ

Ruby,Groovy,JavaScriptインタプリタはまだ多領域をサポートしていません[27]。 つまり、すべての変数はひとつの論理領域のみに定義されていることを意味しています。例えば、Rudyの変数は(インタプリタごとに)一領域中に保存され ます。このように、同ページのであれば、ひとつのウィンドウ中に定義されたインタプリタ変数はほかのウィンドウでオーバーライドされます。混乱を避けるた めに、ウィンドウを意味する特別なプレフィックスのついた変数を書きます。

【ヒント】:どのページもzkscriptコードを処理するために自身のインタプリタを持っています。デスクトップは多数のページを持っていて、(スクリプト言語ごとに)インタプリタが複数のインスタンスを持っている場合があります。

一ページの中にある複数のスクリプト言語

どのスクリプト言語もひとつのインタプリタと繋がっています。変数とメソッドはひとつの言語の中で定義されていて、ほかの言語には使えません。例えば、以下の例の中でvar1とvar2は異なった2つのインタプリタに属しています。

<zscript language="Java">
    var1 = 123;    
</zscript>
<zscript language="JavaScript">
    var2 = 234;    
</zscript>

getVariable と getZScriptVariable

ネーム空間の中で定義された変数はgetVariableメソッドで引き出すことができます。

一方,zscript中で定義された変数はそれを翻訳するインタプリタの一部です。ネーム空間の一部ではありません。つまり、getVariableメソッドでそれらを取得することはできません。

<zscript>
    var1 = 123; //var1 belongs to the interpreter, not any namespace    
    page.getVariable("var1"); //returns null    
</zscript>

代わりにgetZScriptVariableをつかってzscript内で定義された変数を引き出さなければなりません。同様にして、getZScriptClassを使ってクラスを取得し、getZScriptMethodをつかってメソッドを取得します。これらのメソッドは見つかるまで、呼び出されたインタプリタを通して、繰り返されます。

特定のインタプリタを探す場合、以下のようにgetInterpreterメソッドを使って、インタプリタを引き出します。

page.getInterpreter("JavaScript").getVariable("some"); //interpreter for JavaScript
page.getInterpreter(null).getVariable("some"); //interpreter for default language


[25] org.zkoss.zk.scripting.Namespace

[26] 2.3.1(含む)以降および2.2.1(含む)以前、Javaインタプリタはマルチスコープに対応可能です。

[27] 今後サポートする予定です。