1
0
mirror of https://github.com/stedolan/jq.git synced 2024-05-11 05:55:39 +00:00

Clarify the // operator (close #2189)

This commit is contained in:
Nicolas Williams
2023-07-30 18:09:18 -05:00
committed by Nico Williams
parent 949d38e6dc
commit ddef804945
3 changed files with 66 additions and 4 deletions

View File

@ -2384,9 +2384,16 @@ sections:
- title: "Alternative operator: `//`"
body: |
A filter of the form `a // b` produces the same
results as `a`, if `a` produces results other than `false`
and `null`. Otherwise, `a // b` produces the same results as `b`.
The `//` operator produces all the values of its left-hand
side that are neither `false` nor `null`, or, if the
left-hand side produces no values other than `false` or
`true`, then `//` produces all the values of its right-hand
side.
A filter of the form `a // b` produces all the results of
`a` that are not `false` or `null`. If `a` produces no
results, or no results other than `false` or `null`, then `a
// b` produces the results of `b`.
This is useful for providing defaults: `.foo // 1` will
evaluate to `1` if there's no `.foo` element in the
@ -2394,13 +2401,36 @@ sections:
(jq's `or` operator is reserved for strictly Boolean
operations).
Note: `some_generator // defaults_here` is not the same
as `some_generator | . // defaults_here`. The latter will
produce default values for all non-`false`, non-`null`
values of the left-hand side, while the former will not.
Precedence rules can make this confusing. For example, in
`false, 1 // 2` the left-hand side of `//` is `1`, not
`false, 1` -- `false, 1 // 2` parses the same way as `false,
(1 // 2)`. In `(false, null, 1) | . // 42` the left-hand
side of `//` is `.`, which always produces just one value,
while in `(false, null, 1) // 42` the left-hand side is a
generator of three values, and since it produces a
value other `false` and `null`, the default `42` is not
produced.
examples:
- program: 'empty // 42'
input: 'null'
output: ['42']
- program: '.foo // 42'
input: '{"foo": 19}'
output: ['19']
- program: '.foo // 42'
input: '{}'
output: ['42']
- program: '(false, null, 1) // 42'
input: 'null'
output: ['1']
- program: '(false, null, 1) | . // 42'
input: 'null'
output: ['42', '42', '1']
- title: try-catch
body: |

20
jq.1.prebuilt generated
View File

@ -2571,15 +2571,25 @@ jq \'[true, false | not]\'
.IP "" 0
.
.SS "Alternative operator: //"
A filter of the form \fBa // b\fR produces the same results as \fBa\fR, if \fBa\fR produces results other than \fBfalse\fR and \fBnull\fR\. Otherwise, \fBa // b\fR produces the same results as \fBb\fR\.
The \fB//\fR operator produces all the values of its left\-hand side that are neither \fBfalse\fR nor \fBnull\fR, or, if the left\-hand side produces no values other than \fBfalse\fR or \fBtrue\fR, then \fB//\fR produces all the values of its right\-hand side\.
.
.P
A filter of the form \fBa // b\fR produces all the results of \fBa\fR that are not \fBfalse\fR or \fBnull\fR\. If \fBa\fR produces no results, or no results other than \fBfalse\fR or \fBnull\fR, then \fBa // b\fR produces the results of \fBb\fR\.
.
.P
This is useful for providing defaults: \fB\.foo // 1\fR will evaluate to \fB1\fR if there\'s no \fB\.foo\fR element in the input\. It\'s similar to how \fBor\fR is sometimes used in Python (jq\'s \fBor\fR operator is reserved for strictly Boolean operations)\.
.
.P
Note: \fBsome_generator // defaults_here\fR is not the same as \fBsome_generator | \. // defaults_here\fR\. The latter will produce default values for all non\-\fBfalse\fR, non\-\fBnull\fR values of the left\-hand side, while the former will not\. Precedence rules can make this confusing\. For example, in \fBfalse, 1 // 2\fR the left\-hand side of \fB//\fR is \fB1\fR, not \fBfalse, 1\fR \-\- \fBfalse, 1 // 2\fR parses the same way as \fBfalse, (1 // 2)\fR\. In \fB(false, null, 1) | \. // 42\fR the left\-hand side of \fB//\fR is \fB\.\fR, which always produces just one value, while in \fB(false, null, 1) // 42\fR the left\-hand side is a generator of three values, and since it produces a value other \fBfalse\fR and \fBnull\fR, the default \fB42\fR is not produced\.
.
.IP "" 4
.
.nf
jq \'empty // 42\'
null
=> 42
jq \'\.foo // 42\'
{"foo": 19}
=> 19
@ -2587,6 +2597,14 @@ jq \'\.foo // 42\'
jq \'\.foo // 42\'
{}
=> 42
jq \'(false, null, 1) // 42\'
null
=> 1
jq \'(false, null, 1) | \. // 42\'
null
=> 42, 42, 1
.
.fi
.

14
tests/man.test generated
View File

@ -769,6 +769,10 @@ false
null
[false, true]
empty // 42
null
42
.foo // 42
{"foo": 19}
19
@ -777,6 +781,16 @@ null
{}
42
(false, null, 1) // 42
null
1
(false, null, 1) | . // 42
null
42
42
1
try .a catch ". is not an object"
true
". is not an object"