Short arguments are incorrectly handled
The argparser documentation for ‘short’ arguments do not mention any limits on them. It’s fairly common to have two or three-letter abbreviations as the short option form of a long option which is a phrase of multiple words. A user just reported that in my use of it in Resorter, it’s broken.
Consider this shortened example:
#!/usr/bin/Rscript
library(argparser)
p <- arg_parser("foo", name="bar")
p <- add_argument(p, "--no-scale", short="-ns", flag=TRUE, "Do not discretize/bucket the final estimated latent ratings into 1-l levels/ratings; print out inferred latent scores.")
argv <- parse_args(p)
print(argv)
If you run it with -h
, it looks exactly as you would expect, the short version is identical to the long version:
$ ./foo.R -h
Loading required package: methods
usage: bar [--] [--help] [--no-scale] [--opts OPTS]
foo
flags:
-h, --help show this help message and exit
-ns, --no-scale Do not discretize/bucket the final estimated latent ratings into 1-l levels/ratings; print out inferred latent scores.
optional arguments:
-x, --opts RDS file containing argument values
If you try to run it, however, it becomes clear that -ns
is, contrary to -h
, not handled as it’s supposed to be:
$ ./foo.R -ns
Loading required package: methods
usage: bar [--] [--help] [--no-scale] [--opts OPTS]
foo
flags:
-h, --help show this help message and exit
-ns, --no-scale Do not discretize/bucket the final estimated latent ratings into 1-l levels/ratings; print out inferred latent scores.
optional arguments:
-x, --opts RDS file containing argument values
Error in parse_args(p) :
Extra arguments supplied: expecting 0 values but got 2 values: (-n, -s).
Execution halted
$ ./foo.R --no-scale
Loading required package: methods
[[1]]
[1] FALSE
$help
[1] FALSE
$no_scale
[1] TRUE
$opts
[1] NA
argparser should handle short arguments as expected and indicated by -h
; failing that, it should not allow short arguments it cannot handle, and the documentation should explain what limits there are on short arguments.
Comments (5)
-
repo owner -
repo owner To be clear, the intended fix will not make your program functional. It will only throw an error for your program due to incompatibility with POSIX standard, so you should change your program to only use a single character for each short-form.
-
repo owner For your reference,
--no-scale
might be abbreviated to-S
, just as--scale
might be abbreviated-s
, based on typical behaviours for POSIX compliant programs. -
reporter I see, thanks for adding the checks.
I did think about having a
-S
and the user who pointed out the bug suggested as much, but I dislike it as it is inherently misleading; ‘S' suggests ‘scale’, as in, the opposite of ‘no scale’. Making it ‘S’ (not scaling) vs ‘s' (scaling) may be what some programs do but I find that very unintuitive and didn’t realize that was how one might deal with POSIX, and I’ve used the CLI for ~15 years now. Better to just not provide a short argument for that. -
repo owner - changed status to resolved
- Log in to comment
This behaviour is due to the partial support of the POSIX standard requested quite a few versions ago.
As per POSIX standard, flags can be concatenated together, so
-ns
is interpreted as-n
and-s
.Therefore, it is illegal for the short forms to contain multiple characters. You should be using the long-form instead.
I’ll add a check in
add_argument
to prevent the developer from specifying arguments having short-forms that contain multiple characters, and additional documentation describing this behaviour. This will however technically be a compatibility breaking change, which will delay release to CRAN. (Granted, I don’t think any existing programs that rely short-form flags with multiple characters are working as intended.)