|=.? returns empty
vintnes opened this issue · comments
Thank you for this life-changing language. I regret that my first correspondence is a complaint.
Try-catch returns empty following filter assignment.
Input
jq -nc '{foo: "bar"} | .foo |= .?'
Expected output
{"foo":"bar"}
Actual output
{}
Furthermore, //
is unable to catch the result:
$ jq -nc '{foo: "bar"} | .foo |= ( .? // "baz" )'
{}
Environment (please complete the following information):
- Debian Stretch, jq 1.5
- jqplay, jq 1.6
This is an extremely minimized example; I'm actually trying to process incoming strings which may or may not contain valid JSON, as in .value |= (fromjson? // .)
. I catch some undocumented error formatting when I try this:
$ jq -nc '{value: "[]"} | .value |= try fromjson catch .'
{"value":{"__jq":0}}
Thanks again for your efforts.
That's a known bug that I think is fixed on master. If you're able, can you try building master from source?
@wtlangford Would you happen to have a link to the existing issue? I will close this as duplicate.
Sure, it's issue #2011
This is a different issue and reproducible with the master version.
% jq --version
jq-master-a17dd32
% jq -nc '{foo: "bar"} | .foo |= .?'
{}
% jq -nc '{foo: "bar"} | .foo |= ( .? // "baz" )'
{}
% jq -nc '{value: "[]"} | .value |= try fromjson catch .' # yes this works
{"value":[]}
Tentatively reopening on the basis that ? //
has documented behavior different from that of try catch
, specifically that catch .
should return an error string, while // .
should return the most recently piped input.
Also thought I should include my 1.5 workaround in case some poor soul with a conservative distro finds this thread because of the fromjson
references:
.value as $string | .value = ( $string | fromjson? // . )
I think FORK_OPT
(and DESTRUCTURE_ALT
) should only react to the errors inside their scopes while FORK
can be backtracked from anywhere (even from after emitting a value). Can we pop the fork stack when it gets out of the try catch
scope or distinguish backtracks and errors completely by creating another forkopt stack?
Alright, now we're talking! @itchyny please see this branch https://github.com/leonid-s-usov/jq/tree/bt_signalling
It has a complete revision of the backtrack signaling and I actually have pushed some changes to DESTRUCTURE_ALT based on the new signalling here wtlangford#2
I'm finishing some scope of work at my day job and then have the plan to get back on track with the changes mentioned. It's a bit ambitious, cause it involves the dlopen initiative of @nicowilliams , but we'll pull it out this summer, I believe
Okay, thanks for explanation. I finally understand what #1859 (comment) means and it fixes various issues around this subject.
Regarding DESTRUCTURE_ALT
, I noticed that the the subsequent expressions
is not clear in the document if the subsequent expression returns an error, the alternative operator will attempt to try the next binding
.
% jq -n '[0] as [$x] ?// $x | $x[0]' # ok
0
% jq -n '[0] as [$x] ?// $x | $x | .[0]' # still the subsequent expression?
0
% jq -n '([0] as [$x] ?// $x | $x) | .[0]' # is this ok? or should be an error?
0
% jq -n '([0] as [$x] ?// $x | $x) | type | error' # should be number?
jq: error (at <unknown>): array
% jq -n '([2] as $x ?// [$x] | $x) * ([3] as $x ?// [$x] | $x)' # useful? or should be an error?
6
After encountering this error, I asked about it on Stackoverflow. One reply contained a link to this issue
Update operator yields empty object in JQ
~ jq --version
jq-1.6-145-ga9f97e9-dirty
~ jq -nc '{foo: "bar"} | .foo |= .?'
null