APLデータバインディング構文


APLデータバインディング構文

Alexa Presentation Language(APL)ドキュメントが表示されるときにAlexaによって評価される式を記述するには、データバインディング構文を使用します。データバインディング式を使用すると、コンポーネントプロパティをデータソースにバインドしたり、Viewportの特性などの条件に応じてコンポーネントを表示または非表示にする条件付きロジックを作成したりできます。

データバインディング式について

データバインディング式は、JSON文字列内で使用します。データバインディング式の形式は「${expression}」です。"${2}+${2} = ${2+2}"のように、任意の数の式を文字列内に記述できます。

式は現在のデータバインディングコンテキスト内で評価されます。データバインディングコンテキストは、ブール値、数値、文字列、配列、オブジェクト、null値、定義済みのリソースへの参照をサポートするグローバルディクショナリーです。

サポートされる値のタイプ

識別子

識別子は、データバインディング変数を識別するために使用される名前です。識別子は、C識別子の命名規則である[a-zA-Z_][a-zA-Z0-9_]*に従う必要があります。つまり、識別子は大文字または小文字のASCII英文字かアンダースコアで始まり、その後に0文字以上のASCII英文字、数字、アンダースコアを続けます。

${data}
${_myWord23}
${__AnUgly26_letter__examplE}

文字列リテラル

文字列は、一重引用符または二重引用符を使用して定義します。開始と終了の引用符はセットで使用する必要があります。引用符、キャリッジリターン、改行はエスケープ文字で表します。

	${"二重引用符で囲まれた文字列"}
	${'一重引用符で囲まれた文字列'}
	${"内部の引用符:\"または'"}

式は文字列の中に入れ子にすることもできます。

	${"2たす2は${2+2}"}

数値

正の数、負の数、浮動小数点数がサポートされます。指数表記には対応していません。すべての数値は、内部では倍精度浮動小数点数として格納されます。

${1}
${-34.75}
${64000000000}

ブール値

truefalseのブール値がサポートされます。

	${true}
	${false}

null

null定数がサポートされます。

	${null}

配列

角かっこ内にカンマ区切りの式のリストを指定することで、データバインディング式の中で配列を定義できます。

${["A", "B", "C"].length}     // 3に評価
${["on","off"][0]}            // "on"に評価
${[true,"true",1][0]}         // ブール値のtrueに評価

マップ

中かっこ内に文字列キーと値のペアを指定することで、データバインディング式の中でマップオブジェクトを定義できます。

${{"A":1, "B":2}["A"]}    // 1に評価

リソース

定義済みのリソースをデータバインディングコンテキストで参照するには、予約文字@を使用します。次に例を示します。

${@myBlue}
${@isLandscape ? @myWideValue : @myNarrowValue}

データバインディングに公開するリソースは、APLパッケージで定義します。

絶対ディメンション

ディメンションサフィックスは、数値を絶対Viewportディメンションに変換します。有効なディメンションサフィックスは、dppxvhvwです。

${23 dp}     // 23ディスプレイ非依存ピクセル
${10 px}     // 10ピクセル
${50 vw}     // Viewportの幅の50%
${100vh}     // Viewportの高さの100%

ディメンションサフィックスは数値に続ける必要があり、複雑な式には使用できません。たとえば、${(20*20) dp}は有効ではありませんが、${20*20dp}は有効です。

Truthyと強制

データバインディング式では、さまざまなデータ型が使用されます。これらの型はほかの型に変換できます。次の表は、さまざまな変換の例を示しています。この表の例では、Viewportの幅が512dp、DPIが320であると想定しています。

オブジェクト ブール値 数値 文字列 ディメンション
Null null false 0 "" transparent 0dp
ブール値 true true 1 "true" transparent 0dp
ブール値 false false 0 "false" transparent 0dp
数値 23 true 23 "23" #00000017 23dp
数値 0 false 0 "0" transparent 0dp
文字列 "私の犬" true 0 "私の犬" transparent 0dp
文字列 "" false 0 "" transparent 0dp
文字列 "-2.3" true -2.3 "-2.3" transparent -2.3dp
文字列 "red" true 0 "red" #ff0000ff 0dp
文字列 "50vw" true 50 "50vw" transparent 256dp
配列 [] true 0 "" transparent 0dp
マップ {} true 0 "" transparent 0dp
red true 0 "#ff0000ff" #ff0000ff 0dp
ディメンション 32px true 16 "16dp" transparent 16dp
ディメンション 0vh false 0 "0dp" transparent 0dp
ディメンション 23% true 0.23 "23%" transparent 23%
ディメンション 0% false 0 "0%" transparent 0%
ディメンション auto true 0 "auto" transparent auto
その他 ... true 0 "" transparent 0dp
             

ブール型の強制

truthy値とは、真偽を判定するコンテキストで評価したときにtrueと見なされる値です。false0""、絶対ディメンションまたは相対ディメンションの0、nullを除いて、すべての値はtruthyです。

数値の強制

ブール型のtrue値は数値の1に変換されます。文字列値はC++のstd::stodメソッドを使用して変換され、ロケールの影響を受けます。絶対ディメンションはディスプレイに依存しないピクセル数に変換されます。相対ディメンションは割合の値に変換されます(たとえば、32%0.32に変換されます)。それ以外の場合はすべて0に変換されます。

文字列の強制

内部の型は、次の表に示すルールに従って文字列に変換されます。

オブジェクト 結果 説明
Null null '' null値は表示されません。
ブール値 true 'true' ブール値のtruefalseは文字列として表示されます。
  false 'false'  
数値 -23 '-23' 整数では、小数点以下の桁は表示されません。
  1/3 '0.333333' 非整数では、小数点以下の桁が表示されます。
文字列 "私の\"犬\" " '私の"犬" ' 文字列値です。
配列 [...] '' 配列は表示されません。
マップ {...} '' マップは表示されません。
red '#ff0000ff' 色は#rrggbbaaの形式で表示されます。
ディメンション 23 dp '20dp' 絶対ディメンションは、サフィックスdpを付けて表示されます。
ディメンション 20 % '20%' パーセントディメンションは、サフィックス%を付けて表示されます。
ディメンション auto 'auto' 自動ディメンションは「auto」として表示されます。
その他 ${Math.min} '' 数学関数は表示されません。

整数以外の数値に対する固有の形式は定義されていませんが、C++標準のsprintf(buf, "%f", value)に従います。この形式は、ロケールに応じて変わる可能性があります。

色の強制

色の値は、内部的に32ビットのRGBA値として格納されます。数値は32ビットの符号なし整数として扱われ、直接変換されます。文字列値は、色のデータ型の規則に従って解析されます。

絶対ディメンションの強制

数値はdp単位の測定値であると見なされ、絶対ディメンションに変換されます。文字列値は、ディメンションのデータ型の規則に従って解析されます。その他のすべての値は0になります。

相対ディメンションの強制

数値は割合と見なされ、直接変換されます。たとえば、0.5は50%に変換されます。文字列は、ディメンションのデータ型の規則に従って解析されます。その他のすべての値は0になります。

演算子

APLでは、算術演算子、論理演算子、比較演算子、三項演算子がサポートされています。

算術演算子

APLでは、加算、減算、乗算、除算、剰余の標準的な算術演算子がサポートされています。

${1+2}  // 3
${1-2}  // -1
${1*2}  // 2
${1/2}  // 0.5
${1%2}  // 1

加算と減算は、数値のペア、絶対ディメンション、相対ディメンションに対して機能します。数値が絶対ディメンションまたは相対ディメンションのいずれかと組み合わされると、その数値は適切なディメンションに強制変換されます。

加算演算子は、左オペランドか右オペランドが文字列の場合、文字列を連結する演算子としても使用できます。

${27+''}     // '27'
${1+' dog'}  // '1 dog'
${'have '+3} // 'have 3'

乗算演算子、除算演算子、剰余演算子は、数値のペアに対して機能します。乗算は、一方のオペランドが相対ディメンションまたは絶対ディメンションで、もう一方のオペランドが数値の場合にも機能します。この計算結果はディメンションになります。除算は、第1オペランドが相対ディメンションまたは絶対ディメンションで、第2オペランドが数値の場合にも機能します。この計算結果はディメンションになります。

剰余演算子はJavaScriptと同じように機能します。

${10 % 3}  // 1
${-1 % 2}  // -1
${3 % -6}  // 3
${6.5 % 2} // 0.5

論理演算子

APLでは、標準的なAND、OR、NOTの論理演算子がサポートされています。

${true || false}   // true
${true && false}   // false
${!true}           // false

&&は、第1オペランドがtrueと見なされない場合は第1オペランドを返し、そうでない場合は第2オペランドを返します。||演算子は、第1オペランドがtrueと見なされる場合は第1オペランドを返し、そうでない場合は第2オペランドを返します。

${7 && 2}    // 2
${null && 3} // null
${7 || 2}    // 7
${0 || -16}  // -16

比較演算子

比較演算子はブール値を返します。

${1 < 2}
${75 <= 100}
${3 > -1}
${4 >= 4}
${myNullValue == null}
${(2>1) == true}
${1 != 2}

比較演算子は、配列やオブジェクトには適用されません。

比較演算子では、型の強制は行われません。たとえば、${1=='1'}という式はfalseを返します。次の表は、有効な比較の一覧です。その他の比較はすべてfalseを返します。

比較の種類 <、>、<=、>= ==、!= 備考

数値から数値

有効

有効

数値から絶対ディメンション

有効

有効

数値はディスプレイに依存しないピクセルディメンションとして扱われます。

数値から相対ディメンション

有効

有効

数値はパーセンテージとして扱われます。たとえば、0.4は40%と等値です。

相対ディメンションから相対ディメンション

有効

有効

ディメンションはパーセンテージとして比較されます。

絶対ディメンションから絶対ディメンション

有効

有効

ディメンションはディスプレイに依存しないピクセル数に変換されます。

文字列から文字列

有効

有効

ブール値からブール値

false

有効

色から色

false

有効

NullからNull

false

有効

${null==null}はtrueです。

自動ディメンションから自動ディメンション

false

有効

2つの自動ディメンションは、最終的なサイズが等しくなくても等値になります。

その他のすべての組み合わせ

false

false

APLの==演算子は、JavaScriptの===演算子に似ています。

Null合体

??演算子はnull合体演算子です。左オペランドがnullでない場合はそのオペランドを返し、それ以外の場合は右オペランドを返します。null合体演算子は連鎖させることができます。

${person.name ?? person.surname ?? 'Hey, you!'}

null合体演算子は、左オペランドがnull以外であればそのオペランドを返します。

${1==2 ?? 'Dog'}   // returns false
${1==2 || 'Dog'}   // 「Dog」が返される

三項演算子

三項条件演算子${a ? b : c}は左オペランドを評価します。trueまたはtruthy値に評価された場合は、中央のオペランドを返します。そうでない場合は、右オペランドを返します。

${person.rank > 8 ? 'General' : 'Private'}

配列とオブジェクトへのアクセス

配列

配列へのアクセスには[]演算子を使用します。この場合、オペランドは整数でなければなりません。配列は、配列の長さを返す.length演算子もサポートしています。配列の範囲外の要素にアクセスすると、nullが返されます。

${myArray[4]}     // 配列の5番目の要素(0から始まるインデックス)
${myArray.length} // 配列の長さ
${myArray[-1])}   // 配列の最後の要素
${myArray[myArray.length]}  // nullが返される(範囲外)

負のインデックスを渡すと、配列を後ろから数えます。

${a[-1] == a[a.length - 1]}  // true

オブジェクト

オブジェクトでは、.(ドット)演算子と[]配列アクセス演算子での文字列値の使用がサポートされます。

${myObject.name}    // myObjectの「name」プロパティ
${myObject['name']} // myObjectの「name」プロパティ

プロパティが定義されていない場合、式はnullを返します。

nullに対して.(ドット)演算子または[]演算子を呼び出すと、nullが返されます。

${myNullObject.address.zipcode}  // nullが返される

ドット演算子の右オペランドは、有効な識別子でなければなりません。

関数呼び出し

データバインディングでは、いくつのビルトイン関数がサポートされています。関数の形式は次のとおりです。

functionName( arg1, arg2, … )

関数の引数は必須ではありません。関数は単一の値を返します。さまざまな関数式の例を以下に示します。

${Math.floor(1.1)}       // 1
${Math.ceil(1.2)}        // 2
${Math.round(1.2)}       // 1
${Math.min(1,2,3,4)}     // 1
${Math.max(1,2,3,4)}     // 4
${String.toUpperCase('Hello')}    // HELLO
${String.toLowerCase('Hello')}    // hello
${String.slice('Hello', 1, -1)}   // ell

使用可能な関数は、トップレベルのプロパティによってグループ化されています。

配列関数(Array)

トップレベルのArrayプロパティは、配列を操作するための関数と定数のコレクションです。

以下のの列では、サンプルの配列としてa = [101,102,103,104,105,106]が使用されています。

関数 説明
Array.indexOf(x,y) 配列xの要素yのインデックスを返します。配列xyが含まれない場合は、-1を返します。 ${Array.indexOf(a,102)} == 1
Array.range(start, end, [step])

startから開始し、endに達する前までstepごとに増加する数値を要素とする配列を返します。

  • stepは省略可能で、デフォルトは1です。
  • startは省略可能で、デフォルトは0です。stepも省略してendだけを指定することもできます。たとえば、Array.range(10)は、0~9の数値配列を返します。
  • Array.range(0)Array.range(10,3)Array.range(1,5,0)など、無効な引数を渡した場合は空の配列を返します。

${Array.range(1,10,2)} == [1,3,5,7,9]

${Array.range(2,5)} == [2,3,4]

${Array.range(10)} == [0,1,2,3,4,5,6,7,8,9

Array.slice(array,start[,end])

インデックスstartから開始して、インデックスendの前までの要素を含むarrayのサブセットを返します。

  • endは省略可能で、デフォルトは配列の長さになります。
  • startまたはendに負の値を指定すると、配列の末尾から選択されます。
${Array.slice(a,3)} == [104,105,106]
${Array.slice(a,1,3)} == [102,103]
${Array.slice(a,-2)} == [105,106]

ログ関数(Log)

トップレベルのLogプロパティは、Logコマンドから出力されるログメッセージを処理するための便利なメソッドを提供します。

関数 説明

Log.levelName(x)

ログレベルの名前を返します。

${Log.levelName(Log.DEBUG)} == 'debug'

Log.levelValue(x)

ログレベルの値を返します。

${Log.levelValue('info') > Log.levelValue('debug')} == true

Logコマンドで説明されている各レベルに相当する数値として、以下の定数が用意されています。これらは数値の昇順に並んでいます。

  • Log.DEBUG
  • Log.INFO
  • Log.WARN
  • Log.ERROR
  • Log.CRITICAL

各定数の具体的な値は変更される可能性があります。そのため、値は直接使用しないでください。これらの定数間の関係は信頼でき、 常にLog.DEBUG < Log.INFO < Log.WARN < Log.ERROR < Log.CRITICALとなります。

マップ関数(Map)

トップレベルのMapプロパティは、マップを操作するための関数のコレクションです。

次の表に示す例では、xはマップ{'a': 'alpha', 'b': 'bravo'}を想定しています。

関数 説明

Map.keys(x)

マップxのキーの配列を返します。

${Map.keys(x)} == ['a', 'b']

マップ以外に対してMap.keys(x)を呼び出すと、空の配列が返されます。空でない配列に対してMap.keys(x)を呼び出したときに返されるキーの順序は未定義です。

次の例には、文字から単語へのマップを表すmapDataというデータソースが含まれています。ドキュメントはSequenceを表示し、Map.keys関数を使用して、マップ内のすべてのキーの配列をdataプロパティに割り当てます。Sequenceでは、${data}という式でキーにアクセスし、${mapData[data]}という式で値にアクセスできます。


数学関数(Math)

トップレベルのMathプロパティは、数値を計算するための関数と定数のコレクションです。

関数 説明

Math.abs(x)

xの絶対値を返します。

${Math.abs(-2.3)} == 2.3

Math.acos(x)

xのアークコサインを返します。

${Math.acos(1)} == 0

Math.acosh(x)

xの双曲線アークコサインを返します。

${Math.acosh(1)} == 0

Math.asin(x)

xのアークサインを返します。

${Math.asin(0)} == 0

Math.asinh(x)

xの双曲線アークサインを返します。

${Math.asinh(2)} == 1.4436354751788103

Math.atan(x)

xのアークタンジェントを返します。

${Math.atan(1)} == 0.7853981633974483

Math.atanh(x)

xの双曲線アークタンジェントを返します。

${Math.atanh(0.5)} == 0.5493061443340548

Math.atan2(y,x)

y/xのアークタンジェントを返します。

${Math.atan2(1,0)} == 1.5707963267948966

Math.cbrt(x)

xの立法根を返します。

${Math.cbrt(8)} == 2

Math.ceil(x)

x以上の最小の整数を返します。

${Math.ceil(2.3)} == 3

Math.clamp(x,y,z)

y<xの場合はx、y>zの場合はz、それ以外の場合はyを返します。

${Math.clamp(1, 22.3,10)} == 10

Math.cos(x)

xのコサインを返します。

${Math.cos(0)} == 1

Math.cosh(x)

xの双曲線コサインを返します。

${Math.cosh(0)} == 1

Math.exp(x)

eのx乗を返します。eはオイラー定数です。

${Math.exp(1)} == 2.718281828459045

Math.exp2(x)

2のx乗を返します。

${Math.exp2(5)} == 32

Math.expm1(x)

eのx乗マイナス1を返します。

${Math.expm1(1)} == 1.718281828459045

Math.float(x)

xを浮動小数点数に変換します。末尾に「%」文字を付けた場合はパーセンテージを表します。

${Math.float('23.4')} == 23.4
${Math.float('23.4%')} == 0.234

Math.floor(x)

x以下の最大の整数を返します。

${Math.floor(2.3)} == 2

Math.hypot(x1,x2,…)

引数の2乗の和の平方根を返します。

${Math.hypot(3,4)} == 5

Math.int(x,[b=10])

xを整数に変換します。bは文字列変換に使用するオプションの基数です。0で自動検出するか、2~36で基数を定義します。

${Math.int('23.3')} == 23
${Math.int('20', 16)} == 32
${Math.int('0x20', 0)} == 32

Math.isFinite(x)

xが有限の場合はtrueを返します。xが無限または非数(NaN)の場合はfalseを返します。

${Math.isFinite(1.0)} == true
${Math.isFinite(1/0)} == false
${Math.isFinite(0/0)} == false

Math.isInf(x)

xが無限の場合はtrueを返します。

${Math.isInf(1/0)} == true
${Math.isInf(-1/0)} == true
${Math.isInf(0/0)} == false
${Math.isInf(1.0)} == false

Math.isNaN(x)

xが非数(NaN)の場合はtrueを返します。

${Math.isNaN(0/0)} == true
${Math.isNaN(1/0)} == false
${Math.isNaN(1.0)} == false

Math.log(x)

xの自然対数を返します。

${Math.log(Math.E)} == 1

Math.log1p(x)

1+xの自然対数を返します。

${Math.log1p(1)} == 0.6931471805599453

Math.log10(x)

xの底を10とする対数を返します。

${Math.log10(100)} == 2

Math.log2(x)

xの底を2とする対数を返します。

${Math.log2(32)} == 5

Math.max(x1,x2,…)

最大の引数を返します。

${Math.max(2,3)} == 3

Math.min(x1,x2,…)

最小の引数を返します。

${Math.min(2,3)} == 2

Math.pow(x,y)

xのy乗を返します。

${Math.pow(3,4)} == 81

Math.random()

0と1の間の乱数を返します。

${Math.random()} == 0.7113654073137101(実際に返される乱数はこれとは異なります)

Math.round(x)

xに最も近い整数を返します。

${Math.round(2.3)} == 2

Math.sign(x)

xの符号を返します。-10+1のいずれかになります。

${Math.sign(-43.1) == -1

Math.sin(x)

xのサインを返します。

${Math.sin(Math.PI/6)} == 0.5

Math.sinh(x)

xの双曲線サインを返します。

${Math.sinh(1)} == 1.1752011936438014

Math.sqrt(x)

xの平方根を返します。

${Math.sqrt(9)} == 3

Math.tan(x)

xのタンジェントを返します。

${Math.tan(Math.PI/4)} == 1

Math.tanh(x)

xの双曲線タンジェントを返します。

${Math.tanh(10)} == 0.9999999958776927

Math.trunc(x)

xの整数部を返します。

${Math.trunc(-1.2)} == -1

定数 説明
Math.E オイラーの定数(e) 2.718281828459045
Math.LN2 2の自然対数 0.6931471805599453
Math.LN10 10の自然対数 2.302585092994046
Math.LOG2E eの底を2とする対数 1.4426950408889634
Math.LOG10E eの底を10とする対数 0.4342944819032518
Math.PI 円周率(π) 3.141592653589793
Math.SQRT1_2 0.5の平方根 0.7071067811865476
Math.SQRT2 2の平方根 1.4142135623730951

文字列関数(String)

トップレベルのStringプロパティは、文字列を操作するための関数のコレクションです。

関数 説明

String.charAt(x,y)

文字列xから、インデックスyに位置する文字を返します。yが負の数の場合、文字列の末尾から選択します。

${String.charAt('école', 0)} == 'é' ${String.charAt('école', -2)} == 'l'

String.includes(x,y[,z])

文字列xに部分文字列yが含まれている場合はtrueを返します。オプションのインデックスzを指定すると、その位置から検索を開始します。zが負の数の場合は文字列の末尾から検索します。zを省略すると、インデックス0から検索が開始されます。xyが見つからない場合はfalseを返します。

${String.includes('berry', 'erry')} == true
${String.includes('go', 'mango')} == false
${String.includes('abcabc', 'abc', 4)} == false
${String.includes('abcabc', 'a', -1)} == false
${String.includes('abcabc', 'c', -1)} == true

String.indexOf(x,y[,z])

文字列xを検索し、部分文字列yが、オプションのインデックスz以降に最初に出現する位置のインデックスを返します。zが負の数の場合は文字列の末尾から検索します。zを省略すると、文字列xの先頭から検索が開始されます。部分文字列が見つからない場合は-1を返します。

${String.indexOf('berry', 'be')} == 0
${String.indexOf('berryberry', 'er')} == 1
${String.indexOf('abcabc', 'bc', 2)} == 4
${String.indexOf('abcabc', 'bc', 5)} == -1
${String.indexOf('abcabc', 'a', -3)} == 3

String.lastIndexOf(x,y[,z])

文字列xを検索し、指定された部分文字列yが、オプションのインデックスz以前に最後に出現する位置を返します。zが負の数の場合は文字列の末尾から検索します。zを省略すると、文字列xの末尾から検索が開始されます。部分文字列が見つからない場合は-1を返します。

${String.lastIndexOf('berber', 'er')} == 4
${String.lastIndexOf('hello', 'e')} == 1
${String.lastIndexOf('abcabc', 'abc', 4)} == 3
${String.lastIndexOf('abcabc', 'a', -4)} == 0

String.length(x)

文字列の長さを返します。

${String.length('schön')} == 5

String.slice(x,y[,z])

インデックスyから開始して、インデックスzの前までのxのサブセットを返します。zを省略すると、残りの文字列が返されます。yが負の数の場合、文字列の末尾から選択します。

${String.slice('berry', 2, 4)} == 'rr'
${String.slice('berry', -2)} == 'ry'

String.toLowerCase(x)

文字列を小文字にします。

${String.toLowerCase('bEn')} == 'ben'

String.toUpperCase(x)

文字列を大文字にします。

${String.toUpperCase('bEn')} == 'BEN'

文字列のlength関数とslice関数は、バイトではなくUnicodeコードポイントで動作します。

以下は、いくつかのString関数の例を示しています。この例では遅延評価も使用されます。データソースには、関数の例が、#{...}プレースホルダーを持つデータバインディング式として格納されています。これにより、ドキュメントは関数のテキストを表示した後、eval()を使用して関数を評価し、その結果を表示できます。


時間関数(Time)

トップレベルのTimeプロパティは、ミリ秒単位の時間値から年、月、日、時、分、秒に変換する関数のコレクションです。この表の例では、バインドされた時間値がT=1567786974710であると想定しています。人間が判読できる表記にすると、2019年9月6日金曜日の16:22:54と710ミリ秒です。

関数 説明
Time.year(x) 年を返します。 ${Time.year(T)} == 2019
Time.month(x) 月(0~11)を返します。 ${Time.month(T)} == 8(9月)
Time.date(x) 月内の日付(1~31)を返します。 ${Time.date(T)} == 6
Time.weekDay(x) 週内の曜日(0~6)を返します。 ${Time.weekDay(T)} == 5(金曜日)
Time.hours(x) 1日のうちの時間(0~23)を返します。 ${Time.hours(T)} == 16
Time.minutes(x) 1時間のうちの分(0~59)を返します。 ${Time.minutes(T)} == 22
Time.seconds(x) 1分のうちの秒(0~59)を返します。 ${Time.seconds(T)} == 54
Time.milliseconds(x) ミリ秒(0~999)を返します。 ${Time.milliseconds(T)} == 710
Time.format(f, x) 書式設定されたテキスト文字列を返します。 ${Time.format('H:mm', T)} == "16:22"

基本的なデジタル時計を作成するには、TextコンポーネントとlocalTimeプロパティを使用して時間関数を呼び出し、24時間形式の時刻を表示します。

{
  "type": "Text",
  "bind": {
    "name": "T",
    "value": "${localTime}"
  },
  "text": "${Time.hours(T)}:${Time.minutes(T)}"
}

この例では、テキストの式を短縮するためにlocalTimeの値をローカル変数Tにバインドしています。この時計は、午後4時04分のような時刻を16:4としてレンダリングしますが、これは期待した形式ではない可能性があります。条件文を使用して時刻を確認すると、必要に応じて先頭や末尾に0を含めることができます。

次の例に示すように、条件文を使用して12時間時計を表示することもできます。これは時間と分の両方をローカル変数にバインドし、条件文を使用して、12時間形式の時刻にamまたはpmを付けて出力します。

{
  "type": "Text",
  "bind": [
    {
      "name": "h",
      "value": "${Time.hours(localTime)}"
    },
    {
      "name": "m",
      "value": "${Time.minutes(localTime)}"
    }
  ],
  "text": "${h >= 12 ? h - 12 : h}:${m < 10 ? '0' : ''}${m} ${h >= 12 ? 'pm' : 'am'}"
}

Time.format関数を使用してコードを単純化することもできます。次の例では、時間に基づく条件文を使用して、最後に「am」または「pm」を追加します。

{
  "type": "Text",
  "bind": [
    {
      "name": "h",
      "value": "${Time.hours(localTime)}"
    }
  ],
  "text": "${Time.format('h:mm', localTime) + (h >= 12 ? ' pm' : ' am')}"
}


Time.format

format関数は、書式コードと時刻値を含む文字列引数を受け取ります。次の書式コードがサポートされています。

範囲 説明
YY 00~99 2桁の年
YYYY 1970~XXXX 4桁の年
M 1~12 月(1=1月)
MM 01~12 2桁の月(1=1月)
D 1~31 月内の日付
DD 01~31 月内の2桁の日付
DDD 0~N エポックからの日数(桁数不定)
H 0~23 24時間表記の時間
HH 00~23 24時間表記の2桁の時間
HHH 0~N エポックからの時間数(桁数不定)
h 1~12 12時間表記の時間
hh 01~12 12時間表記の2桁の時間
m 0~59
mm 00~59 2桁の分
mmm 0~N エポックからの分数(桁数不定)
s 0~59
ss 00~59 2桁の秒
sss 0~N エポックからの秒数(桁数不定)
S 0~9 デシ秒
SS 00~99 センチ秒
SSS 000~999 ミリ秒

すべての書式コードは数字のみを返します。

次の表は、2019年9月6日16:22:54と710ミリ秒という時間値を使用した場合の書式設定関数の例を示しています。

書式
DD-MM-YYYY 06-09-2019
M/D/YY 9/6/19
DDD日 18145日(エポック以降)
H:mm 16:22
hh:mm 04:22
H:mm:ss 16:22:54

時刻の書式は、タイマーからの相対時間にも適用できます。次の表は、7523194という値を使用した場合の例を示しています。この値は2時間5分23.194秒に相当します。

書式
mmm:ss.S 125:23.1
HHH:mm:ss.SS 2:05:23.19
sss.SSS 7523.194

次の例では、elapsedTimeを使用してドキュメントが読み込まれてからの経過時間を表示します。サンドボックス内のタイマーを再起動するには、ページを更新してください。


データバインディングの文字列の変換

APLはJSONでシリアル化されているため、すべてのデータバインド式はJSON文字列内で定義されます。

{
  "MY_EXPRESSION": "${....}"
}

引用符とデータバインディング式の間にスペースがない場合、式の結果はデータバインディング評価の結果になります。次に例を示します。

"${true}"               -> ブール値のtrue
"${2+4}"                -> 数値6
"${0 <= 1 && 'three'}"  -> 文字列「three」

文字列内のデータバインディング式の外側にスペースがある場合、または2つのデータバインディング式が並んでいる場合、結果は連結された文字列になります。

" ${true}"     -> 文字列「 true」
"${2+4} "      -> 文字列「6 」
"${2+1}${1+2}" -> 文字列「33」

遅延評価

APLでプロパティやバインド変数が評価されるときには、${...}構文で記述された式が評価され、解決されます。場合によっては、この評価を遅延させて、式を解決するタイミングを制御できると便利です。APLバージョン2023.2以降では、#{...}プレースホルダーとeval()ビルトイン関数を使用して、式の評価を遅延させることができます。eval()は、データソース内の式など、自動的には評価されない式を評価するためにも使用できます。

遅延プレースホルダー構文

データバインディングの評価により、#{...}プレースホルダーは標準のデータバインディング式に置き換えられます。ただし、その式の評価は実行されません。つまり、${...}構文が残ります。次の例は、textプロパティで#{...}構文を使用するTextコンポーネントを示しています。

{
  "type": "Text",
  "text": "式#{1+2}は${1+2}に評価されます"
}

この文字列の通常の評価結果は、"式${1+2}は3に評価されます"という文字列になります。${1+2}という式は文字列内に残ります。

#{...}プレースホルダー内の文字列は有効なAPL式である必要があり、そうでない場合は置換に失敗します。以下は、2つの項目を持つbind配列の例です。変数X${1+a}に解決されます。変数Yは、1+が有効な式でないため、評価に失敗します。その結果、Yには#{1+}が含まれたままになります。

"bind": [
  {
    "name": "X",
    "value": "#{1+a}"
  },
  {
    "name": "Y",
    "value": "#{1+}"
  }
]

eval()関数

eval()ビルトイン関数は、引数を1つ受け取り、その引数に対してデータバインディングアルゴリズムを実行します。引数は、#{...}プレースホルダーで作成された文字列か、データソースで提供された文字列です。

次の例は、3つのbind項目を示しています。Formatは遅延データバインディング構文を使用し、Greetingeval()関数を呼び出します。

"bind": [
  {
    "name": "Format",
    "value": "こんにちは、#{Name}さん"
  },
  {
    "name": "Name",
    "value": "クリス"
  },
  {
    "name": "Greeting",
    "value": "${eval(Format)}"
  }
]

バインディングは次の値に解決されます。

Format   = "こんにちは、${Name}さん"
Name     = "クリス"
Greeting = "こんにちは、クリスさん"

次の例に示すように、eval()呼び出しは入れ子にすることもできます。

"bind": [
  {
    "name": "A",
    "value": "#{B}"
  },
  {
    "name": "B",
    "value": "#{C}"
  },
  {
    "name": "C",
    "value": "こんにちは"
  },
  {
    "name": "D",
    "value": "${eval(A)}"
  },
  {
    "name": "E",
    "value": "${eval(eval(A))}"
  }
]

この例のバインディングは次の値に解決されます。

A = "${B}"
B = "${C}"
C = "こんにちは"
D = "${C}"
E = "こんにちは"

eval(A)を呼び出した結果は、"こんにちは"ではなく"${C}"になることに注意してください。

リソースのローカライゼーションに遅延評価を使用する

遅延評価を使用すると、resourcesとして定義される項目に動的なデータを埋め込むことができます。この手法は、言語固有の文字列を書式設定する場合に便利です。

次の例では、異なるロケールに応じて異なる書式を使用するTEMPERATURE_FORMATリソースを定義します。データソースのロケールを変更して、画面が更新されることを確認してください。


この例では、言語に応じて温度を地域に適した形式に変換します。en-US環境では、APLはリソースを次の値に設定します。

CELSIUS            = "${TEMP} °C"
FAHRENHEIT         = "${TEMP * 9 / 5 + 32} °F"
TEMPERATURE_FORMAT = "The temperature is ${TEMP * 9 / + 32} °F" // 「en-US」の句を選択
text               = "The temperature is 77 °F"

textプロパティのeval()呼び出しにより、TEMP=25.0を使用してTEMPERATURE_FORMAT文字列が評価され、"The temperature is 77 °F"という結果に変換されます。SetValueなどによってTEMPの値を変更すると、textプロパティで式が再評価され、コンポーネントが更新されます。

遅延評価とデータソース

eval()関数を使用すると、データソースでドキュメントに渡されたデータバインディング式を評価することもできます。

デフォルトでは、データバインディングの評価はデータソース内の式を処理しません。たとえば、データソースのプロパティを${1+2}に設定し、そのデータソースのプロパティをドキュメント内のコンポーネントにバインドしたとします。このコンポーネントがインフレートされたとき、コンポーネントのプロパティには、評価結果の"3"ではなく"${1+2}"というテキストが含まれます。

データソースのプロパティ内のデータバインディング式を処理するには、プロパティをeval()関数に渡します。

次の例は、データソースでeval()関数を使用する方法を示しています。


eval()による配列とオブジェクトの処理

配列またはオブジェクトに対してeval()関数を呼び出すと、配列の各エントリやオブジェクトの各プロパティが個々に評価されます。この機能は、一連の書式文字列を処理する場合に役立ちます。

たとえば、2つのプロパティを持つオブジェクトXがあり、それらのプロパティにデータバインディング式が含まれているとします。

X = {
  "formal_greeting": "${NAME}様、お世話になっております",
  "casual_greeting": "${NAME}さん、こんにちは"
}
NAME = "ラージ"

Xeval()に渡すと、各プロパティが解決されたオブジェクトが返されます。

eval(X) = {
  "formal_greeting": "ラージ様、お世話になっております",
  "casual_greeting": "ラージさん、こんにちは"
}

次の例は、オブジェクトに対してeval()を呼び出すAPLドキュメントを示しています。


遅延評価のガイドライン

eval()関数はコストが高い

eval()関数では、関数呼び出しのたびに式が解析され、評価されます。つまり、eval()関数はコストが高い操作です。eval()を使用する前に、別のアプローチを使用できないかどうかを検討してください。

eval()の再起呼び出しは避ける

終了しないeval()の再起呼び出しを作成しないように注意してください。

次の例では、自身に対してeval()を呼び出すbind変数Aが作成されます。

再帰呼び出しの例

{
  "type": "Text",
  "bind": {
    "name": "A",
    "value": "ハッ#{eval(A)}"
  },
  "text": "私は無敵だ!${eval(A)}!"
}

APLでは、再帰的な評価の呼び出しの深さが制限されています。そのため、この例では、無限に長い文字列が作成される代わりに、「私は無敵だ! ハッ ハッ ハッ${eval(A)}!」のようなテキストが表示される可能性があります。上限は3以上であることが保証されていますが、特定のランタイムではそれよりも大きい値になることがあります。


このページは役に立ちましたか?

最終更新日: 2025 年 11 月 04 日