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:
committed by
Nico Williams
parent
949d38e6dc
commit
ddef804945
@ -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
20
jq.1.prebuilt
generated
@ -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
14
tests/man.test
generated
@ -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"
|
||||
|
Reference in New Issue
Block a user