{entry; ...}
{
}
はオブジェクトを作るリテラルです。
括弧内には、 ;
で区切って0個以上のエントリーを書くことができます。
{
}
は文レベルの場所に書かれても、コードブロックではなくオブジェクトリテラルとして振舞います。
$ flc '{a: 1; b: 2}'
# {a:1;b:2}
;
で区切られた項が key: value
の形式であることは強制ではなく、実際には2要素の配列、およびそのストリームを受け付けます。
エントリー演算子 :
は、オブジェクトリテラルとは本質的に無関係な、両辺を2要素の配列にする演算子です。
$ flc '{1 .. 3 | "Item$_": _ * 10; 4 .. 6 | ["Item$_", _ * 100]}'
# {Item1:10;Item2:20;Item3:30;Item4:400;Item5:500;Item6:600}
オブジェクトリテラル内での ;
の記述は柔軟です。
項の前後や中間に ;
を余計に多く書いても問題ありません。
また、改行は ;
の代わりになります。
$ flc '{
a: 1
b: 2
; ; ; c: 3; ; ;
}'
# {a:1;b:2;c:3}
オブジェクトリテラル内で変数を宣言した場合、その変数はオブジェクトのエントリーに含まれつつ、オブジェクトリテラル内からも名前でアクセスできます。
$ flc '
{
fruit := "apple"
result: fruit & fruit
}
'
# {fruit:apple;result:appleapple}
オブジェクトリテラル内で宣言された変数にアクセスすると、そのエントリはその時点でオブジェクトに代入されます。
$ flc '
{
result: fruit & fruit
fruit := "apple"
}
'
# {fruit:apple;result:appleapple}
この例では、 result
の値を計算する時点では fruit
にはまだ値が設定されていないため、アクセスした時点で初期化が行われます。
object()
配列のストリーム化と似ていますが、こちらは各エントリーのキーと値で構成される配列のストリームを返します。
$ flc '{a: 1; b: 2; c: 3}()'
# [a;1]
# [b;2]
# [c;3]
以下は、オブジェクトを、各キーの末尾に z
を付け、各値を10倍したオブジェクトにする例です。
$ flc '{a: 1; b: 2; c: 3}() | (_.0 & "z": _.1 * 10) >> TO_OBJECT'
# {az:10;bz:20;cz:30}
object(key)
配列の要素アクセスと概ね同じですが、キーには文字列が使われます。
$ flc '{a: 1; b: 2; c: 3}("b")'
# 2
$ flc '{a: 1; b: 2; c: 3}("b", "a")'
# 2
# 1
$ flc '"b", "a", "c" >> {a: 1; b: 2; c: 3}'
# 2
# 1
# 3
オブジェクトの要素アクセスは実際には _()
メソッドの呼び出しであり、オーバーライドができます。
これにより関数のように振舞うオブジェクトを作ることができます。
$ flc '
adder := {
`_()`: this, a, b -> a + b
}{}
adder(10; 20)
'
# 30
$ flc '
adder := {
`_()`: {
`_()`: this2, this1, a, b -> a + b
}{}
}{}
adder(10; 20)
'
# 30
object.key = value
でオブジェクトの要素に値を代入できます。
$ flc '
object := {
a: "one"
b: "two"
c: "three"
}
object.b = 99999
object
'
# {a:one;b:99999;c:three}
キーがそのオブジェクトにまだ存在しない場合は新たに追加されます。