Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add debug/1 to log debug messages without consuming stdin #2478

Closed
wants to merge 1 commit into from

Conversation

yertto
Copy link

@yertto yertto commented Sep 3, 2022

Define debug/1 to call debug/0, but send stdin to stdout without consuming it,
while printing the debug messages to stderr.

Example usage:

seq 2 | jq '
  debug({$ENV})                          |
  debug({line: input_line_number})       |
  debug("\(now | todate) here1: .=\(.)") |
  . * 10                                 |
  debug("\(now | todate) here2: .=\(.)") |
  . + 1
'

=>

["DEBUG:",{"ENV":{"PWD":"/tmp","SHELL":"/bin/zsh","PATH":"/usr/bin:/bin", ...}}]
["DEBUG:",{"line":1}]
["DEBUG:","2022-09-03T10:52:24Z here1: .=1"]
["DEBUG:","2022-09-03T10:52:24Z here2: .=10"]
11
["DEBUG:",{"ENV":{"PWD":"/tmp","SHELL":"/bin/zsh","PATH":"/usr/bin:/bin", ...}}]
["DEBUG:",{"line":2}]
["DEBUG:","2022-09-03T10:52:24Z here1: .=2"]
["DEBUG:","2022-09-03T10:52:24Z here2: .=20"]
21

ie. a slightly less efficient way of achieving:

seq 2 | jq '
   . * 10 |
   . + 1
'

=>

11
21

@yertto yertto changed the title Define debug/1 in terms of debug/0 feat: Define debug/1 in terms of debug/0 Sep 3, 2022
@yertto yertto changed the title feat: Define debug/1 in terms of debug/0 feat: Add debug/1 to log debug messages without consuming stdin Sep 3, 2022
@yertto yertto force-pushed the yertto/debug_1 branch 7 times, most recently from 8359b61 to d7f69ea Compare September 3, 2022 12:58
Define `debug/1` to call `debug/0`, but send `stdin` to `stdout` without consuming it,
while printing the debug messages to `stderr`.

Example usage:
```sh
seq 2 | LOG_LEVEL=DEBUG jq '
  debug({$ENV})                          |
  debug({line: input_line_number})       |
  debug("\(now | todate) here1: .=\(.)") |
  . * 10                                 |
  debug("\(now | todate) here2: .=\(.)") |
  . + 1
'
```
=>
```
["DEBUG:",{"ENV":{"PWD":"/tmp","SHELL":"/bin/zsh","PATH":"/usr/bin:/bin", ...}}]
["DEBUG:",{"line":1}]
["DEBUG:","2022-09-03T10:52:24Z here1: .=1"]
["DEBUG:","2022-09-03T10:52:24Z here2: .=10"]
11
["DEBUG:",{"ENV":{"PWD":"/tmp","SHELL":"/bin/zsh","PATH":"/usr/bin:/bin", ...}}]
["DEBUG:",{"line":2}]
["DEBUG:","2022-09-03T10:52:24Z here1: .=2"]
["DEBUG:","2022-09-03T10:52:24Z here2: .=20"]
21
```

ie. a *slightly* less efficient way of achieving:
```sh
seq 2 | jq '
   . * 10 |
   . + 1
'
```
=>
```
11
21
```
@ck3d
Copy link

ck3d commented Sep 3, 2022

I appreciate your PR, since I have to define the same function for complex jq programs.

@yertto
Copy link
Author

yertto commented Sep 3, 2022

I have to define the same function for complex jq programs.

@ck3d - yer I know - right?

The manual currently just says:

debug
Causes a debug message based on the input value to be produced. The jq executable wraps the input value with ["DEBUG:", ] and prints that and a newline on stderr, compactly. This may change in the future.

Have you seen any mentions anywhere else, as to when or what it might change to?
ie. as debug/0 (especially without an example) isn't particularly useful.

@ck3d
Copy link

ck3d commented Sep 3, 2022

No, I have no idea. I am more an heavy user of jq not a developer.

@yertto
Copy link
Author

yertto commented Sep 3, 2022

Actually @ck3d,
I've just noticed my PR is a duplicate of @andremarianiello's #2112 (from 2 years ago) which never got merged.
So how bout I close this PR & we pop over to that one and 👍 it?

@yertto yertto closed this Sep 3, 2022
@emanuele6
Copy link
Member

emanuele6 commented Sep 3, 2022

When I need to debug stuff adding information to the debug message, I usually use:

empty = ("something: \(.)" | debug)

This works because the rhs of assignments other than the update assignment (|=) is not lazily evaluated; this can be annoying at times, but it allows to write | empty = code_with_side_effects | ... as a convenient short form for | (code_with_side_effects | empty), ... |.


As a side note: here is an overload for = that lazily evaluates rhs that i wrote a while ago for who is interested :):

def _assign(p;v):
    . as $dot |
    reduce ([ "o" ] + path(p)) as $p ({ o: . };
        setpath($p; .v //= ($dot | [ v ]) | .v[])) |
    .o;
bash-5.1$ <<< '"hi"' jq -c '(arrays[1:] | .. | numbers) = first'
jq: error (at <stdin>:1): Cannot index string with number
bash-5.1$ <<< '["hi",1,[2,false,3,4]]' jq -c '(arrays[1:] | .. | numbers) = first'
["hi","hi",["hi",false,"hi","hi"]]
bash-5.1$ <<< '"hi"' jq -c '
> def _assign(p;v): . as $dot | reduce ([ "o" ] + path(p)) as $p ({ o: . }; setpath($p; .v //= ($dot | [ v ]) | .v[])) | .o;
> (arrays[1:] | .. | numbers) = first
> '
"hi"
bash-5.1$ <<< '["hi",1,[2,false,3,4]]' jq -c '
> def _assign(p;v): . as $dot | reduce ([ "o" ] + path(p)) as $p ({ o: . }; setpath($p; .v //= ($dot | [ v ]) | .v[])) | .o;
> (arrays[1:] | .. | numbers) = first
> '
["hi","hi",["hi",false,"hi","hi"]]

@yertto
Copy link
Author

yertto commented Sep 4, 2022

@emanuele6 - Ahh brilliant, thanks for the explanation!

I wonder if debug/1 would get more use from folks who don't know how to use it with empty = like this,
but I guess I understand what the entry for empty in the manual means now...

empty
empty returns no results. None at all. Not even null.

It's useful on occasion. You'll know if you need it :)

@emanuele6 emanuele6 mentioned this pull request Jul 11, 2023
@yertto
Copy link
Author

yertto commented Nov 17, 2023

Closed by #2710

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants