mike-neckのブログ

Java or Groovy or Swift or Golang

jq のバインディングオペレーターを使ったときの挙動が怪しいときに見るべきページはここ

問題

次の jq スクリプトを実行したときの結果はどうなるか? ただし、 jq コマンドのオプションには -n-r を与える。

(0, 1, 2) |
. * 2 as $m |
"[\(.) -> \($m)]"

回答選択肢

(1)

[0 -> 0]
[1 -> 2]
[2 -> 4]

(2)

null
null
null

(3)

実行時エラー

(4)

null
[1 -> 2]
[2 -> 2][2 -> 2]

(5)

構文エラー


正解

(4) が答え。

フィルターの解釈的に . * 2 as $m | "[\(.) -> \($m)]". *2 as $m | "[\(.) -> \($m)]" の2つに解釈されるらしい

ちなみに

range(3) |
. * 2 |
"becomes \(.)"

は次のようになる

becomes 0
becomes 2
becomes 4

なお、バインディングオペレーターもフィルターの一つと言えるので、2つのパイプの中にフィルターを複数置くとこのような事象が発生するのかと言うと…

def isOdd: . % 2 == 1;
range(3) |
. * 2 isOdd |
"becomes \(.)"

これは構文エラーになる


以上の結果から

バインディングオペレーターはフィルターでありながらパイプの中に 2 つのフィルターが構文的に置けることになり、2 つのフィルターをおいた際に、現在のフィルターと後続のパイプの計算の優先順位が変わってくる

と言える