DSL operators¶
Detailed listing¶
Operators are listed on the DSL built-in functions page.
Operator precedence¶
Operators are listed in order of decreasing precedence, highest first.
Operators | Associativity |
---|---|
() {} [] |
left to right |
** |
right to left |
! ~ unary+ unary- |
right to left |
. |
left to right |
* / // % |
left to right |
binary+ binary- |
left to right |
<< >> >>> |
left to right |
& |
left to right |
^ |
left to right |
| |
left to right |
< <= > >= |
left to right |
== != =~ !=~ <=> |
left to right |
??? |
left to right |
?? |
left to right |
&& |
left to right |
^^ |
left to right |
|| |
left to right |
? : |
right to left |
= |
N/A for Miller (there is no $a=$b=$c) |
See also the section on parsing and operator precedence in the REPL for information on how to examine operator precedence interactively.
Operator and function semantics¶
-
Functions are often pass-throughs straight to the system-standard Go libraries.
-
The
min
andmax
functions are different from other multi-argument functions which return null if any of their inputs are null: formin
andmax
, by contrast, if one argument is absent-null, the other is returned. Empty-null loses min or max against numeric or boolean; empty-null is less than any other string. -
Symmetrically with respect to the bitwise OR, AND, and XOR operators
|
,&
, and^
, Miller has logical operators||
,&&
, and^^
. -
The exponentiation operator
**
is familiar from many languages, except that an integer raised to an int power is int, not float. -
The regex-match and regex-not-match operators
=~
and!=~
are similar to those in Ruby and Perl.
The double-purpose dot operator¶
The main use for the .
operator is for string concatenation: "abc" . "def"
is "abc.def"
.
However, in Miller 6 it has optional use for map traversal. Example:
cat data/server-log.json
{ "hostname": "localhost", "pid": 12345, "req": { "id": 6789, "method": "GET", "path": "api/check", "host": "foo.bar", "headers": { "host": "bar.baz", "user-agent": "browser" } }, "res": { "status_code": 200, "header": { "content-type": "text", "content-encoding": "plain" } } }
mlr --json --from data/server-log.json put -q ' print $req["headers"]["host"]; print $req.headers.host; '
bar.baz bar.baz [ ]
This also works on the left-hand sides of assignment statements:
mlr --json --from data/server-log.json put ' $req.headers.host = "UPDATED"; '
[ { "hostname": "localhost", "pid": 12345, "req": { "id": 6789, "method": "GET", "path": "api/check", "host": "foo.bar", "headers": { "host": "UPDATED", "user-agent": "browser" } }, "res": { "status_code": 200, "header": { "content-type": "text", "content-encoding": "plain" } } } ]
A few caveats:
- This is why
.
has higher precedece than+
in the table above -- in Miller 5 and below, where.
was only used for concatenation, it had the same precedence as+
. So you can now do this:
mlr --json --from data/server-log.json put -q ' print $req.id + $res.status_code '
6989 [ ]
- However (awkwardly), if you want to use
.
for map-traversal as well as string-concatenation in the same statement, you'll need to insert parentheses, as the default associativity is left-to-right:
mlr --json --from data/server-log.json put -q ' print $req.method . " -- " . $req.path '
(error) [ ]
mlr --json --from data/server-log.json put -q ' print ($req.method) . " -- " . ($req.path) '
GET -- api/check [ ]