Introspection: Difference between revisions

Content added Content deleted
(Frink)
(→‎{{header|jq}}: update, with reference also to gojq)
Line 960: Line 960:


=={{header|jq}}==
=={{header|jq}}==
jq's powers of introspection are currently very limited, being
essentially confined to the built-in function `builtins`, which
as the name suggests only yields information about built-in filters (name and arity).


'''Works with jq, the C implementation of jq'''
Version information can however be made available to a running jq program as illustrated here:


'''Works with gojq, the Go implementation of jq'''
jq --arg version $(jq --version) '$version'


jq's support for introspection is limited. For example, jq's version
References to undefined functions and undefined variables (that is jq's "$-variables")
number is available from the command-line but not as a built-in; and
are regarded as errors that cannot be caught, but in a pinch one can use the
it is not in general possible to check whether a variable has been
technique illustrated here:
defined without causing an error. However, jq does make it possible
for a program to check whether a variable has been defined globally,
so we'll go with that.


Note that jq's `builtins` function provides details about jq's built-in
jq -n --argjson bloop null 'if $bloop then $bloop|length else "undefined" end'
functions, and similarly the `modulemeta` function provides some support for
introspection within modules, but otherwise there is no support for
determining the functions that have been user-defined.


Assuming JQ has been defined appropriately as a shell. variable, one could
As it happens, jq's "abs" function is named "length" (don't ask why),
invoke jq with a global "bloop" variable as follows:
so the task regarding `abs()` cannot really be accomplished using the name `abs`.
<pre>
$JQ -n --arg version "$($JQ --version)" --argjson bloop -3 -f introspection.jq
</pre>

The following program has been tested with recent versions of both jq
and gojq, but may fail with earlier versions. Note also that
jq's `length` has the semantics of `abs` when applied to numbers,
so if your jq does not support `abs` by that name, you could use `length`.

<syntaxhighlight lang="jq">
def checkVersion:
$version
| capture("^[^- ]*(?<jq>[- ])(?<major>[0-9]*)[.](?<minor>[0-9]*)") // {jq: 0}
| if .jq == 0 then "unrecognized version identification: \($version)" | error
elif .jq == "-" # jq
and (.major < "1" or (.major == "1" and .minor < "5"))
then "version \($version) is too old" | error
elif .jq == " " # gojq
and (.major == "0" and (.minor | tonumber) < 12)
then "version \($version) is too old" | error
else .
end;

checkVersion
# Check that abs/0 is defined
| (builtins | index("abs/0")) as $ix
| if $ix == null then "abs/0 not available" | error else . end

# Is bloop a global variable?
| if ($ARGS.named | has("bloop")) then $ARGS.named["bloop"] | abs
else "There is no globally defined variable name $bloop." | error
end
</syntaxhighlight>
Examples:
{{output}}
<pre>
$ gojq -n --arg version "$(gojq --version)" --argjson bloop -3 -f introspection.jq
3

$ jq -n --arg version "$(jq --version)" -f introspection.jq
jq: error (at <unknown>): There is no globally defined variable name bloop.
</pre>


=={{header|Jsish}}==
=={{header|Jsish}}==