diff --git a/docs/src/example-mlr-s-script b/docs/src/example-mlr-s-script index 50e3f5db4..69d1e1638 100755 --- a/docs/src/example-mlr-s-script +++ b/docs/src/example-mlr-s-script @@ -1,4 +1,4 @@ -#!/usr/bin/env mlr -s +#!/usr/bin/env -S mlr -s --c2p filter '$quantity != 20' # Here is a comment then count-distinct -f shape diff --git a/docs/src/online-help.md b/docs/src/online-help.md index bb8185e10..f112b1e18 100644 --- a/docs/src/online-help.md +++ b/docs/src/online-help.md @@ -61,6 +61,7 @@ Flags: mlr help format-conversion-keystroke-saver-flags mlr help json-only-flags mlr help legacy-flags + mlr help markdown-only-flags mlr help miscellaneous-flags mlr help output-colorization-flags mlr help pprint-only-flags diff --git a/docs/src/reference-dsl-builtin-functions.md b/docs/src/reference-dsl-builtin-functions.md index 1b3b1af40..fa93a240b 100644 --- a/docs/src/reference-dsl-builtin-functions.md +++ b/docs/src/reference-dsl-builtin-functions.md @@ -1217,12 +1217,13 @@ collapse_whitespace (class=string #args=1) Strip repeated whitespace from strin ### contains
-contains (class=string #args=2) Returns true if the first argument contains the second as a substring. This is like saying `index(arg1, arg2) >= 0`but with less keystroking.
+contains (class=string #args=2) Returns true if the first argument contains the second as a substring. This is like saying `index(arg1, arg2) >= 0` but with less keystroking. Stringifies non-string scalar inputs; raises an error if either argument is an array or map. To test for array membership, use `any`, e.g. `any([1,2,3], func(e) {return e == $foo})`.
Examples:
contains("abcde", "e") gives true
contains("abcde", "x") gives false
contains(12345, 34) gives true
contains("forêt", "ê") gives true
+contains([1,2,3], 2) gives (error)
@@ -1258,12 +1259,13 @@ gsub("prefix4529:suffix8567", "(....ix)([0-9]+)", "[\1 : \2]") gives "[prefix :
### index
-index (class=string #args=2) Returns the index (1-based) of the second argument within the first. Returns -1 if the second argument isn't a substring of the first. Stringifies non-string inputs. Uses UTF-8 encoding to count characters, not bytes.
+index (class=string #args=2) Returns the index (1-based) of the second argument within the first. Returns -1 if the second argument isn't a substring of the first. Stringifies non-string scalar inputs; raises an error if either argument is an array or map. Uses UTF-8 encoding to count characters, not bytes.
Examples:
index("abcde", "e") gives 5
index("abcde", "x") gives -1
index(12345, 34) gives 3
index("forêt", "t") gives 5
+index([1,2,3], 2) gives (error)
diff --git a/docs/src/scripting.md b/docs/src/scripting.md
index 4766dcb50..953687c81 100644
--- a/docs/src/scripting.md
+++ b/docs/src/scripting.md
@@ -35,7 +35,7 @@ circle 3 0.3
Typing this out can get a bit old, if the only thing that changes for you is the filename. Some options include:
* On Linux/Mac/etc you can make a script with `#!/bin/sh` which invokes Miller as part of the shell-script body.
-* On Linux/Mac/etc you can make a script with `#!/usr/bin/env mlr -s` which invokes Miller.
+* On Linux/Mac/etc you can make a script with `#!/usr/bin/env -S mlr -s` which invokes Miller.
* On any platform you can put the reusable part of your command line into a text file (say `myflags.txt`), then `mlr -s myflags-txt filename-which-varies.csv`.
Let's look at examples of each.
@@ -135,7 +135,7 @@ Here instead of putting `#!/bin/bash` on the first line, we can put `mlr` direct
cat ./example-mlr-s-script
-#!/usr/bin/env mlr -s
+#!/usr/bin/env -S mlr -s
--c2p
filter '$quantity != 20' # Here is a comment
then count-distinct -f shape
diff --git a/docs/src/scripting.md.in b/docs/src/scripting.md.in
index f29fe8b63..5b9dee073 100644
--- a/docs/src/scripting.md.in
+++ b/docs/src/scripting.md.in
@@ -13,7 +13,7 @@ GENMD-EOF
Typing this out can get a bit old, if the only thing that changes for you is the filename. Some options include:
* On Linux/Mac/etc you can make a script with `#!/bin/sh` which invokes Miller as part of the shell-script body.
-* On Linux/Mac/etc you can make a script with `#!/usr/bin/env mlr -s` which invokes Miller.
+* On Linux/Mac/etc you can make a script with `#!/usr/bin/env -S mlr -s` which invokes Miller.
* On any platform you can put the reusable part of your command line into a text file (say `myflags.txt`), then `mlr -s myflags-txt filename-which-varies.csv`.
Let's look at examples of each.
diff --git a/pkg/bifs/strings.go b/pkg/bifs/strings.go
index 1cecb39fe..218a03df0 100644
--- a/pkg/bifs/strings.go
+++ b/pkg/bifs/strings.go
@@ -134,6 +134,9 @@ func BIF_index(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
if input1.IsError() {
return mlrval.FromTypeErrorUnary("index", input1)
}
+ if input1.IsArrayOrMap() || input2.IsArrayOrMap() {
+ return mlrval.FromTypeErrorBinary("index", input1, input2)
+ }
sinput1 := input1.String()
sinput2 := input2.String()
@@ -156,6 +159,9 @@ func BIF_contains(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
if input1.IsError() {
return input1
}
+ if input1.IsArrayOrMap() || input2.IsArrayOrMap() {
+ return mlrval.FromTypeErrorBinary("contains", input1, input2)
+ }
return mlrval.FromBool(strings.Contains(input1.String(), input2.String()))
}
diff --git a/pkg/dsl/cst/builtin_function_manager.go b/pkg/dsl/cst/builtin_function_manager.go
index 073a06165..364f98fbd 100644
--- a/pkg/dsl/cst/builtin_function_manager.go
+++ b/pkg/dsl/cst/builtin_function_manager.go
@@ -581,25 +581,27 @@ Arrays are new in Miller 6; the substr function is older.`,
{
name: "index",
class: FUNC_CLASS_STRING,
- help: `Returns the index (1-based) of the second argument within the first. Returns -1 if the second argument isn't a substring of the first. Stringifies non-string inputs. Uses UTF-8 encoding to count characters, not bytes.`,
+ help: `Returns the index (1-based) of the second argument within the first. Returns -1 if the second argument isn't a substring of the first. Stringifies non-string scalar inputs; raises an error if either argument is an array or map. Uses UTF-8 encoding to count characters, not bytes.`,
binaryFunc: bifs.BIF_index,
examples: []string{
`index("abcde", "e") gives 5`,
`index("abcde", "x") gives -1`,
`index(12345, 34) gives 3`,
`index("forêt", "t") gives 5`,
+ `index([1,2,3], 2) gives (error)`,
},
},
{
name: "contains",
class: FUNC_CLASS_STRING,
- help: `Returns true if the first argument contains the second as a substring. This is like saying ` + "`index(arg1, arg2) >= 0`" + `but with less keystroking.`,
+ help: `Returns true if the first argument contains the second as a substring. This is like saying ` + "`index(arg1, arg2) >= 0`" + ` but with less keystroking. Stringifies non-string scalar inputs; raises an error if either argument is an array or map. To test for array membership, use ` + "`any`" + `, e.g. ` + "`any([1,2,3], func(e) {return e == $foo})`" + `.`,
binaryFunc: bifs.BIF_contains,
examples: []string{
`contains("abcde", "e") gives true`,
`contains("abcde", "x") gives false`,
`contains(12345, 34) gives true`,
`contains("forêt", "ê") gives true`,
+ `contains([1,2,3], 2) gives (error)`,
},
},
diff --git a/test/cases/dsl-contains/0002/cmd b/test/cases/dsl-contains/0002/cmd
new file mode 100644
index 000000000..df47a8b50
--- /dev/null
+++ b/test/cases/dsl-contains/0002/cmd
@@ -0,0 +1 @@
+mlr -n put -q -f ${CASEDIR}/mlr
diff --git a/test/cases/dsl-contains/0002/experr b/test/cases/dsl-contains/0002/experr
new file mode 100644
index 000000000..e69de29bb
diff --git a/test/cases/dsl-contains/0002/expout b/test/cases/dsl-contains/0002/expout
new file mode 100644
index 000000000..3cb084ffc
--- /dev/null
+++ b/test/cases/dsl-contains/0002/expout
@@ -0,0 +1,5 @@
+(error)
+(error)
+(error)
+(error)
+(error)
diff --git a/test/cases/dsl-contains/0002/mlr b/test/cases/dsl-contains/0002/mlr
new file mode 100644
index 000000000..209d7c5c7
--- /dev/null
+++ b/test/cases/dsl-contains/0002/mlr
@@ -0,0 +1,7 @@
+end {
+ print contains([1,2,3], 2);
+ print contains("abc", [1,2,3]);
+ print contains({"a":1}, "a");
+ print index([1,2,3], 2);
+ print index("abc", {"k":1});
+}