オブジェクトリテラル {entry; ...}#

{ } はオブジェクトを作るリテラルです。

括弧内には、 ; で区切って0個以上のエントリーを書くことができます。

{ } は文レベルの場所に書かれても、コードブロックではなくオブジェクトリテラルとして振舞います。

$ xa '{a: 1; b: 2}'
# {a:1;b:2}

; で区切られた項が key: value の形式であることは強制ではなく、実際には2要素の配列、およびそのストリームを受け付けます。

エントリー演算子 : は、オブジェクトリテラルとは本質的に無関係な、両辺を2要素の配列にする演算子です。

$ xa '{1 .. 3 | "Item$_": _ * 10; 4 .. 6 | ["Item$_", _ * 100]}'
# {Item1:10;Item2:20;Item3:30;Item4:400;Item5:500;Item6:600}

オブジェクトリテラル内での ; の記述は柔軟です。

項の前後や中間に ; を余計に多く書いても問題ありません。

また、改行は ; の代わりになります。

$ xa '{
  a: 1
  b: 2
  ; ; ; c: 3; ; ;
}'
# {a:1;b:2;c:3}

オブジェクトリテラル内での変数宣言#

オブジェクトリテラル内で変数を宣言した場合、その変数はオブジェクトのエントリーに含まれつつ、オブジェクトリテラル内からも名前でアクセスできます。

$ xa '
  {
    fruit := "apple"
    result: fruit & fruit
  }
'
# {fruit:apple;result:appleapple}

変数にアクセスした時点で初期化される#

オブジェクトリテラル内で宣言された変数にアクセスすると、そのエントリはその時点でオブジェクトに代入されます。

$ xa '
  {
    result: fruit & fruit
    fruit := "apple"
  }
'
# {fruit:apple;result:appleapple}

この例では、 result の値を計算する時点では fruit にはまだ値が設定されていないため、アクセスした時点で初期化が行われます。

オブジェクトのストリーム化 object()#

配列のストリーム化と似ていますが、こちらは各エントリーのキーと値で構成される配列のストリームを返します。

$ xa '{a: 1; b: 2; c: 3}()'
# [a;1]
# [b;2]
# [c;3]

以下は、オブジェクトを、各キーの末尾に z を付け、各値を10倍したオブジェクトにする例です。

$ xa '{a: 1; b: 2; c: 3}() | (_.0 & "z": _.1 * 10) >> TO_OBJECT'
# {az:10;bz:20;cz:30}

オブジェクト呼び出し#

オブジェクトに対して object(key) のように関数呼び出しを行うと、その要素を取得します。

key は文字列化されて評価されます。

key がストリームだった場合、その各要素を文字列化して要素を取得するようなストリームを返します。

$ xa '{a: 1; b: 2; c: 3}("b")'
# 2

$ xa '{a: 1; b: 2; c: 3}("b", "a")'
# 2
# 1

$ xa '"b", "a", "c" >> {a: 1; b: 2; c: 3}'
# 2
# 1
# 3

オブジェクト呼び出しのオーバーライド#

オブジェクトの要素アクセスは実際には _(__) メソッドの呼び出しであり、オーバーライドができます。

これにより関数のように振舞うオブジェクトを作ることができます。

$ xa '
  adder := {
    `_(__)`: this, a, b -> a + b
  }{}
  adder(10; 20)
'
# 30

$ xa '
  adder := {
    `_(__)`: {
      `_(__)`: this2, this1, a, b -> a + b
    }{}
  }{}
  adder(10; 20)
'
# 30

オブジェクト呼び出しへの代入#

object(key) = value のように代入呼び出しが可能です。

key は文字列化されて評価されます。

$ xa '
  obj := {fruit: "apple"}
  obj("fruit") = "banana"
  obj.fruit
'
# banana

オブジェクト呼び出しへの代入のオーバーライド#

オブジェクト呼び出しと同様に、代入操作も _(__)=_ メソッドでオーバーライドできます。

オブジェクトのプロパティアクセス#

object.key でオブジェクトの要素を取得できます。

key が識別子だった場合、それは変数参照ではなく識別子自体を文字列として評価されます。

任意の式によるプロパティアクセスを行うには、 object.(key) のように key 部分を丸括弧で囲みます。

オブジェクトのプロパティアクセスへの代入#

object.key = value でオブジェクトの要素に値を代入できます。

$ xa '
  object := {
    a: "one"
    b: "two"
    c: "three"
  }

  object.b = 99999

  object
'
# {a:one;b:99999;c:three}

キーがそのオブジェクトにまだ存在しない場合は新たに追加されます。

オブジェクトのキーの削除#

object -= key でオブジェクトからエントリーを削除できます。

$ xa '
  object := {a: "apple"; b: "banana"; c: "cherry"}
  object -= "b"
  object
'
# {a:apple;c:cherry}

削除するキーが存在しない場合は何も起こりません。

$ xa '
  object := {a: "apple"; b: "banana"; c: "cherry"}
  object -= "d"
  object
'
# {a:apple;b:banana;c:cherry}

右辺がストリームの場合、その各要素に対してキー削除を行います。

$ xa '
  object := {a: "apple"; b: "banana"; c: "cherry"}
  object -= "a", "c"
  object
'
# {b:banana}