基礎式


図 6.36. 基礎式

正規名称
 | オブジェクトリテラル
 | 'this'
 | 文字列式
 | 明示的な配列式
 | 範囲式
 | ブロック
 | リテラル
 | 関数式
 | '(' 値式 ')'
 | タイムライン式


正規名称

正規名称はパッケージやクラスへの参照です。ドットで区切られたパッケージとサブパッケージのリストで指定された参照です。

図 6.37. 正規名称

名称 ['.' 名称]...

java.lang.Objectは、javaパッケージの中のlangサブパッケージの中のObjectクラスを参照する正規名称です。 ここに正規名称の使い方がいくつかあります。

import java.util.GregorianCalendar;
class FooWriter extends java.io.PrintWriter {}
var baseFile = new java.io.File("base.txt");


オブジェクトリテラル

オブジェクトリテラルはJavaFXスクリプトでインスタンスを生成する基本的な方法です。 関数と、インスタンス変数へのon-replace句の追加も含めて、インスタンスに新しい機能を追加することもできます。

図 6.38. オブジェクトリテラル

正規名称 '{' [ オブジェクトリテラル部分 [','|';']... ] '}'

図 6.39. オブジェクトリテラル部分

変数オーバーライド宣言 | 変数宣言 | 関数定義 | オブジェクトリテラル初期化

図 6.40. オブジェクトリテラル初期化

名称 ':' 初期化式

正規名称はJavaFXスクリプトクラスの参照であるべきです。 (訳注:正規名称ではなく単に名称でいいのでは)

Pointクラスはこのように定義されることを例で示します。

class Point {
   var x : Number;
   var y : Number;
}

オブジェクトリテラルはクラスのインスタンスを生成し、インスタンス変数の初期値を設定します。

def somewhere = Point {
   x: 3.2
   y: 7.8
}

インスタンス変数の初期化式は順不同で書かれ、その初期化式は書いた順に評価されます。

オブジェクトリテラルはインスタンス変数の初期化式の提供を必要としません。 ですが、いくつかのクラスはインスタンスの固有の機能のために、 一部のインスタンス変数が初期化されることを要求します。従ってこれは正しい例です。

def default = Point {}
def high = Point {
   y: 92.1
}

インスタンス変数の初期化についての詳細はクラスの章を参照してください。

オブジェクトリテラルのローカルな変数と関数は、その生成時における支援が提供されています。 ここではローカル変数のradiusが定義されます。

def location = Point {
   def radius = 10.3;
   x: radius * 2
   y: radius * 5
}

しばしばローカル変数は、ネストしたオブジェクトリテラルが相互参照できるように生成するのに使われます。

例:

class Tree {
   var value : String;
   var children : Tree[];
   var previousSibling : Tree;
   function format(indent : String) : String {
      "{indent}{value} "
      "{if (previousSibling != null) '(prev:{previousSibling.value})' else ''}"
      "\n"
      "{for (kid in children) kid.format('   {indent}')}"
   }
}

def root = Tree {
   def tunicates = Tree {
      value: 'Urochordata'
   }
   def skulledBeasts = Tree {
      def hagfish = Tree {
         value: 'Hyperotreti' 
      }
      def us = Tree {
         value: 'Vertebrata'
         previousSibling: hagfish
      }
      value: 'Craniata'
      children: [ hagfish, us ]
      previousSibling: tunicates
   }
   value: 'Chordata'
   children: [ tunicates, skulledBeasts]
}

ネストしたオブジェクトリテラルに兄弟関係を構築させるために、ローカルなdefを使います。

印字結果:

Chordata
   Urochordata
   Craniata (prev:Urochordata)
      Hyperotreti
      Vertebrata (prev:Hyperotreti)

on-replace句の追加が、インスタンス変数のオーバーライドによって、Pointの例に追加されます。

def current = Point {
   override var x on replace { println( "Changed x to {x}" ) }
   override var y on replace { println( "Changed y to {y}" ) }
   x: 66.6
   y: 33.3
}
current.x = 99.9;

印字結果:

Changed x to 66.6 
Changed y to 33.3 
Changed x to 99.9

このオブジェクトリテラル(onCircleに保持されている)の実演のように、 インスタンス変数の初期化式は、単一方向でも双方向でもバインド式にできます。

import java.lang.Math.*;
var angle = 0.0;
def onCircle = Point {
   x: bind cos(angle)
   y: bind sin(angle)
   override function toString() : String { "Point({%4.1f x}, {%4.1f y})" }
}
println( onCircle );
angle = 0.5 * PI;
println( onCircle );
angle = PI;
println( onCircle );
angle = 1.5 * PI;
println( onCircle );
angle = 2 * PI;
println( onCircle );

onCircleのインスタンス変数xは、angleのコサインとして維持され、yはサインとして維持されます。 バインドの詳細はバインドの章を参照してください。 Objectに定義されているtoString関数は、オブジェクトリテラルでより良い出力書式の提供するようにオーバーライドされています。このようにコンソールに印字されます。

Point( 1.0, 0.0) Point( 0.0, 1.0) 
Point(-1.0, 0.0) 
Point(-0.0, -1.0) 
Point( 1.0, -0.0)

オブジェクトリテラルの値は新しいインスタンスになります。オブジェクトリテラルの型は正規名称で与えられた型になります。


this

this式は現在のインスタンスを参照します。

[To do: 例、構文、説明を追加する]


文字列式

図 6.41. 単純化された文字列式

引用符 [文字列 '{' [書式文字列] 値式 '}' ]... 文字列 引用符

二つの引用符にはシングルクォートまたはダブルクォートが適用できます。

文字列リテラルのように、隣接した文字列式(と、文字列リテラル)はコンパイル時に自動的に結合されます。

[[To do: 共通的なサブセットを扱う移植可能な書式を書く。(訳注:意味不明です)]


明示的な配列式

配列の要素を明示的に列挙することで、配列を作ります。

図 6.42. 明示的な配列式

'[' [ 値式 [,...] ] ']'

表 6.9. 明示的な配列式の値

明示的な配列式考察
['One', 'Two', 'Buckle', 'My', 'Shoe'][ 'One', 'Two', 'Buckle', 'My', 'Shoe' ] 明示的なStringの配列
[4, 7, [9, 3], 2][ 4, 7, 9, 3, 2 ] 配列はネストしないので、実装される配列はフラットです。
var x = 32; [x, 4, x][ 32, 4, 32 ] 明示的な配列の構成は値式です。
var seq = ['bop', 'a']; ['be', seq, 'lulu'][ 'be', 'bop', 'a', 'lulu' ] 再度、フラットな配列です。
var nada = null; ['be', nada, 'lulu'][ 'be', 'lulu' ] nullは値の欠如です。よって空の配列が評価され、フラットにされます。


範囲式

IntegerかNumberの値の範囲で配列を作ります。

図 6.43. 範囲式

'[' 値式 '..' ['<'] 値式 ['step' 値式] ']'

配列の開始と終了とステップを与える3つの値式はInteger型かNumber型でなければなりません。 もし、これらのいくつかがNumber型の場合、範囲式はNumberの配列型になり、 そうでなければIntegerの配列型になります。

ステップの値式がもし無い場合、デフォルトは1です。ステップはマイナスの値にもできます。 配列の値はすべて開始の値式と終了の値式の間の値で、そこで値はステップの値式ごとになります。 開始の値式は含まれます。終了の値式..<形式が使われていなければ含まれます。

ここにいくつかの範囲式と、それに対応する値があります。

範囲式考察
[1..5][ 1, 2, 3, 4, 5 ] 暗黙的なステップが提供されているので、デフォルトの1が使われています。 開始を終了の値式がInteger型なので、配列の要素はInteger型です。
[1..<5][ 1, 2, 3, 4 ] 小なり符号が、1(含みます)から5(含みません)までを示しています。
[1 .. 5.0][ 1.0, 2.0, 3.0, 4.0, 5.0 ] 終了の値式がNumber型なので、配列の要素はNumber型です。
[8.6 .. 12][ 8.6, 9.6, 10.6, 11.6 ]8.6, 次は 1 + 8.6, など
[1..9 step 2][ 1, 3, 5, 7, 9 ]明示的なステップは2。 1, 2 + 1, など
[100..90 step -3][ 100, 97, 94, 91 ]マイナスのステップなので値は減少します
[0..1 step 0.25][ 0.0, 0.25, 0.5, 0.75, 1.0 ]分数のステップ
[0..<1 step 0.25][ 0.0, 0.25, 0.5, 0.75 ]終了を含みません
[5..1][ ] 1でステップを刻むと5から1の間に値が無いので、配列の結果は空になります。 開始から終了まで値が反復されるので、これはコンパイラに検出され警告が表示されます。

開始と終了とステップは定数でなくてもよく、不定の値式を使えます。


ブロック

ブロックは式のリストです。ブロックはスコープを形成します。

図 6.44. ブロック

'{' [式 ';']... '}'

ブロックの型は、ブロックの最後の式の型です。ブロックの値は、ブロックの最後の式の値です。

例:

println( {
   var sum = 0;
   var counter = 10;
   while (counter > 0) {
      sum += counter;
      --counter;
   }
   "Sum is {sum}"
} )
ブロックはprintlnで印字されます。


リテラル

リテラル値は型と値の章で述べています。

図 6.45. リテラル

十進数 | 八進数 | 十六進数 | 時刻 | 浮動小数点値 | 'true' | 'false' | 'null'


関数式

関数式は、関数定義を値として表現することを可能にします。

図 6.46. 関数式

'function' 引数宣言 型指示子 ブロック

図 6.47. 引数宣言

'(' [書式引数 ',']... ')'

図 6.48. 書式引数

名称 型指示子

例:

var func : function(:Integer):Integer;
func = function(n : Integer) { 1000 + n }
println( func(7) );
func = function(n : Integer) { n * n }
println( func(7) );

ここでfuncは関数型として宣言された変数です。funcはIntegerを取り1000をそれに加える関数を割り当てられています。 変数に保存された関数が呼び出され、この場合1007が印字されます。 そしてfuncは、入ってくるIntegerを二乗する新しい関数を再度割り当てられます。今度はfunc(7)は49です。

インスタンス変数の初期化式は、インスタンスの状態の初期化を設定するのに使われます。 関数型のインスタンス変数で、関数式はインスタンスに動作を設定するのに使われます。

このクラスはinitial変数とnext関数により一連のStringを作ります。

class SeriesBuilder {
   var initial : String;
   var next : function(:String):String;
   function series(count : Integer) : String[] {
      var current = initial;
      var result = [initial];
      for (idx in [1..count]) {
         current = next(current);
         insert current into result;
      }
      result
   }
}

def aba = SeriesBuilder {
   initial: 'X'
   next: function(curr : String) { "{curr}o{curr}" }
}

def shorten = SeriesBuilder {
   initial: 'lambda'
   next: function(curr : String) { curr.substring(1) }
}

def bop = SeriesBuilder {
   initial: 'Lake'
   next: function(curr : String) { ['Beach', 'Mountains', 'Desert'][curr.length() mod 3] }
}

println( aba.series(4) );
println( shorten.series(5) );
println( bop.series(5) );

三つのまったく異なるStringの配列が、三つの異なるinitial変数とnext関数のペアで作られます。 次のように印字します。

[ X, XoX, XoXoXoX, XoXoXoXoXoXoXoX, XoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX ] 
[ lambda, ambda, mbda, bda, da, a ]
[ Lake, Mountains, Beach, Desert, Beach, Desert ]

タイムライン式

タイムライン式はアニメーションで使われます。アニメーションの章を参照してください。

図 6.49. タイムライン式

'at' '(' タイムリテラル ')' '{' keyFrameリテラル部 '}'

図 6.50. keyFrameリテラル部

{値式 ';'}...


Home