JavaFX Scriptプログラム言語を学ぼう

レッスン2:スクリプトを書く

このレッスンはJavaFX Script言語への実践的な導入を提供します。 その中であなたは変数と関数の基本を、コマンドラインで実行できるシンプルな計算機を書くことによって、学習します。 各セクションはひとつの新しい中心となる概念を紹介し、それを考察し、コンパイルと実行が可能なサンプルを提示します。 その考察は現実的なコードの引用も含んでいて、それは実際のSDKのデモでどのように特定の構造が使われているのかを見せます。 以下の各デモへのリンクはあなたをjavafx.comのウェブサイトに連れて行きます。 そこであなたはコードリストの全体に加えて開発者の補注を入手することができます。

スクリプト変数の宣言


前のレッスンでは開発環境のセットアップを紹介しました。ここでは calculator.fx ソースコードをよく見てみましょう。下の赤で示したコードはプログラムのスクリプト変数を 宣言しています。スクリプト変数はvarかdefキーワードを使って宣言されます。 二つの違いは、var変数がスクリプトが生きている間はずっと新しい値を割り当てることができ、 一方、def変数は最初に割り当てられた値をずっと残します。 ここで私達はいくつかの値をnumOneとnumTwoに割り当てますが、resultは初期化しないままにしておきます。 この変数は将来の計算の結果を保存するからです。


def numOne = 100;
def numTwo = 2;
var result;

add();
subtract();
multiply();
divide();

function add() {
    result = numOne + numTwo;
    println("{numOne} + {numTwo} = {result}");
}

function subtract() {
    result = numOne - numTwo;
    println("{numOne} - {numTwo} = {result}");
}

function multiply() {
    result = numOne * numTwo;
    println("{numOne} * {numTwo} = {result}");
}

function divide() {
    result = numOne / numTwo;
    println("{numOne} / {numTwo} = {result}");
}

これらの変数を数値(文字や他の種類のデータではない)のデータを保存するものとして 特に明示する必要がないことに、気が付くでしょう。 コンパイラは、その変数が使われている文脈からあなたの意図を見つけ出せるほどに賢いです。 これは型の推定として知られています。型の推定はスクリプトプログラマーとしての あなたの仕事をすこし楽にしてくれます。 あなたを、変数が適合するデータ型を宣言する負担から開放するからです。

実際の使用例:Effects Playground

(訳注:上の画像は原文が表示している画像そのものです。)

上のスクリーンショットはデモアプリケーションの"Effects Playground"です。 引用したコードはいくつかのスクリプト変数を表しています。 あなたはリストの全体を - まだ - 理解することはできないでしょう。 しかし強調した位置は今学んだばかりのことを土台にして理解できるはずです。 このチュートリアルは非グラフィカルな、中心の構造だけに注目していることを覚えていてください。 最終的にあなたは自分のGUIベースのアプリケーションにこの知識を使うでしょう。

変数の下位レベルの考察は JavaFX言語リファレンス3章. 変数 をご覧ください。

スクリプト関数の定義と呼び出し


私達の計算機の例はいくつかのスクリプト関数の定義もしていて、それは二つの数値の加算、減算、乗算、除算をします。 関数は実行可能なコードのブロックで、特別な目的を処理します。 下の赤い部分のコードは四つの関数を定義していて、それぞれは簡単な算術計算を実行し、結果を印字します。 コードを関数にまとめることは、プログラムを読みやすく、使いやすく、デバッグしやすくするための一般的な慣習です。 関数の本体は一般的に読みやすさのためにインデントされます。

def numOne = 100;
def numTwo = 2;
var result;

add();
subtract();
multiply();
divide();


function add() {
    result = numOne + numTwo;
    println("{numOne} + {numTwo} = {result}");
}

function subtract() {
    result = numOne - numTwo;
    println("{numOne} - {numTwo} = {result}");
}

function multiply() {
    result = numOne * numTwo;
    println("{numOne} * {numTwo} = {result}");
}

function divide() {
    result = numOne / numTwo;
    println("{numOne} / {numTwo} = {result}");
}

関数のコードはそれが呼び出されるまでは実行されないことも知っているべきです。 これはスクリプトのどこからでも関数を起動できることを可能にしています。 関数の呼び出しは、その関数の定義の前や後に置かれていても構いません。 (例では関数をソースファイルのそれが実際に定義されるよりも前方で呼び出しています。)

def numOne = 100;
def numTwo = 2;
var result;

add();
subtract();
multiply();
divide();

function add() {
    result = numOne + numTwo;
    println("{numOne} + {numTwo} = {result}");
}

function subtract() {
    result = numOne - numTwo;
    println("{numOne} - {numTwo} = {result}");
}

function multiply() {
    result = numOne * numTwo;
    println("{numOne} * {numTwo} = {result}");
}

function divide() {
    result = numOne / numTwo;
    println("{numOne} / {numTwo} = {result}");
}

実際の使用例:Draggable MP3 Player

(訳注:上の画像は原文が表示している画像そのものです。)

"Draggable MP3 Player"デモでは、プログラマーは現在の歌を停止や再生する関数を定義しています。 私達は文脈を完全に離れてコードを見ているにもかかわらず、これらの関数(stopcurrentSongとplauCurrentSong)の名前の選択は、 コードを自己文書化していて、従って、とても解析をしやすくしています。 あなたの変数と関数に名前を付けるとき、このように、つねに意味のある言葉使ってみてください。 慣例では、名前の最初の語は小文字で、それに続くそれぞれの語の一文字目を大文字でつづります。

スクリプト関数の引数


スクリプト関数は引数を定義することもできます。引数は、関数を呼び出すときにあなたが渡す固有の値です。 このやり方で私達は計算機アプリケーションにあらゆる二つの数値の計算を実行させることができます。 numOneとnumTwo変数にハードコードされた値ではありません。 実際このバージョンで、私達はnumOneとnumTwoを完全に削除して、resultを唯一のスクリプト変数として残しました。

var result;

add(100,10);
subtract(50,5);
multiply(25,4);
divide(500,2);

function add(argOne: Integer, argTwo: Integer) {
    result = argOne + argTwo;
    println("{argOne} + {argTwo} = {result}");
}

function subtract(argOne: Integer, argTwo: Integer) {
    result = argOne - argTwo;
    println("{argOne} - {argTwo} = {result}");
}

function multiply(argOne: Integer, argTwo: Integer) {
    result = argOne * argTwo;
    println("{argOne} * {argTwo} = {result}");
}

function divide(argOne: Integer, argTwo: Integer) {
    result = argOne / argTwo;
    println("{argOne} / {argTwo} = {result}");
}

スクリプトの出力は今度はこうです。

100 + 10 = 110
50 - 5 = 45
25 * 4 = 100
500 / 2 = 250

実際の使用例:Interesting Photos

(訳注:上の画像は原文が表示している画像そのものです。)

"Interesting Photos"のデモから引用されたこのコードには、 一連の引数を取るloadImageというスクリプト関数を見ることができます。 ここでも関数と変数の名前の選択がコードの理解を容易にしています。 この関数のすべての実装を理解することは今重要ではありません。 しかしながら大事なことは、二つの引数を取る関数を認識することです。 あなたが自分のアプリケーションを書き始めるときに、 正しい構文の例としてこのようなサンプルコードをたぶん頼りにするでしょう。

スクリプト関数からの戻り値


関数はそれを呼び出すコードに値を戻すこともできます。 例えば、私達は計算機のadd関数にその結果を計算のたびに返すようにできます。

function add(argOne: Integer, argTwo: Integer) : Integer {
     result = argOne + argTwo;
     println("{argOne} + {argTwo} = {result}");
     return result;

}

赤い部分の最初のコードは、関数がIntegerを返すことを、二つ目の部分は実際に値を返すことを示しています。

これからはadd関数はこのように呼び出すことができます。

var total;

total = add(1,300) + add(23,52);

もし返す値が指定されていなければ、関数はデフォルトでVoidを返します。

実際の使用例:Animating Photos from Flickr

(訳注:上の画像は原文が表示している画像そのものです。)

"Animating Photos from Flickr" デモから引用したコードでは、三つの異なる関数で値を返しているのが見られます。 戻り値は今まで見てきたものよりも少し複雑ですが、中心の概念は同じです。 それぞれの関数はいくつかの特定の計算を実行して、結果を返しています。 最初に続く二つ目の関数はMath関数を(平方根を計算するために)呼び出してその結果を返しています。 三つ目の関数は新しいVector2Dオブジェクトを返します。 このリストだけでは、何を意味するのか正確に知るだけの情報がありませんが、 完全なソースコードでは意味を成します。(それが言語にはじめての習得に時間を掛けさせてきたのです。)

関数の下位レベルの考察は Java言語リファレンス4章.関数 をご覧ください。

コマンドライン引数へのアクセス


最後に、スクリプトはコマンドラインの引数を受け取ることもできます。私達の計算機の例では、 エンドユーザに実行時に計算する数値を指定できるようにします。

var result;

function run(args : String[]) {

     // Convert Strings to Integers
     def numOne = java.lang.Integer.parseInt(args[0]);
     def numTwo = java.lang.Integer.parseInt(args[1]);

     // Invoke Functions 
     add(numOne,numTwo);
     subtract(numOne,numTwo);
     multiply(numOne,numTwo);
     divide(numOne,numTwo);
}


function add(argOne: Integer, argTwo: Integer) {
     result = argOne + argTwo;
     println("{argOne} + {argTwo} = {result}");
}

function subtract(argOne: Integer, argTwo: Integer) {
     result = argOne - argTwo;
     println("{argOne} - {argTwo} = {result}");
}

function multiply(argOne: Integer, argTwo: Integer) {
     result = argOne * argTwo;
     println("{argOne} * {argTwo} = {result}");
}

function divide(argOne: Integer, argTwo: Integer) {
     result = argOne / argTwo;
     println("{argOne} / {argTwo} = {result}");
}

この変更はrun関数の導入です。そこではスクリプトがコマンドライン引数を受け取ります。 あなたが見てきた他の関数と違うのは、runは特別な関数で、スクリプトのメインの入り口としての機能を果たすことです。 run関数はすべてのコマンドライン引数をargsに保存し、それはStringオブジェクトのシーケンスになっています。 (シーケンスは順序正しく並んだオブジェクトのリストです。他のプログラム言語の配列と似ています。 レッスン5:配列 で詳細を説明しています。)(注釈:シーケンスはここ以外では「配列」と呼びます。)

このスクリプトを走らせるには、ユーザは実行時に最初と二番目の数値を指定しなければなりません。

javafx calculator 100 50

出力結果はこうなります。

100 + 50 = 150
100 - 50 = 50
100 * 50 = 5000
100 / 50 = 2

計算機スクリプトの前のすべてのバージョンでは、run関数を明示的に用意しなかったことに注意してください。 スクリプトレベルに実行させるコードを打ち込んだだけで、期待通りに動きました。 そのような場合にはコンパイラは無言で、引数のないrun関数を生成して、その中に実行されるコードを起きます。 あなた自身でrun関数を指定したときだけ、argsの名前はあなたの希望するものになります。 私達はargsを使いましたが、あなたは、プログラマーが他の変数を使うのを多分見るでしょう。 "arg", "ARGS", "ARGS", "argv"などです。

このバージョンで私達はnumOneとnumTwo変数を呼び戻したことにも注目してください。 スクリプトレベルの代わりにrun関数の中で今度は定義しています。 (変数が関数の中で定義されると、それは技術的にはローカル変数として知られています。 それは同じ関数の中の他のコードにだけ見えるからです。) 私達の計算機の関数は数値を期待しているのですが、コマンドライン引数は文字列です。 従ってそれぞれのコマンドライン引数を関数に渡す前にStringからIntegerに変換しなければなりません。

// Convert Strings to Integers
def numOne = java.lang.Integer.parseInt(args[0]);
def numTwo = java.lang.Integer.parseInt(args[1]);

これをするためには実際の型変換を行うためにJava言語の助けを得ました。 必要に応じて既存のJavaの生態系をうまく活用することは これや他のシンプルなスクリプト言語にものすごく強い力を発揮させます。

実際の使用例:Brick Breaker

(訳注:上の画像は原文が表示している画像そのものです。)

"Brick Breaker"デモからのこの引用は、ゲームのメインの入り口としての役目を持つrun関数を表しています。 この特定の例はコマンドライン引数を実際には使っていませんが、 run関数がアプリケーションのmainFrameを初期化して、そのtitle, width, heightなどを設定しているのがわかります。


Home