Auto-parse booleans (true / false), nil, and numbers?
borkdude opened this issue ยท 4 comments
It could be reasonable behaviour to auto-parse "false"
as false
and "nil"
as nil
. This would in some cases reduce the amount of :coerce
config to zero.
Furthermore it could also be reasonable behavior to auto-parse 123
as a number.
Anything else is still parsed as a string.
We should be able to disable the auto-parsing.
{:no-auto-parse true}
and/or in the future:
{:no-auto-parse #{:number :number}}
Could there be a case where you want to have a new 1foo
? This seems very unlikely. We could also revert to the string in case of edn/read-string
failure.
Would you have want to have false
, true
? This seems unlikely and if so, you could coerce them to strings, if that is desired.
Here are some examples of conventions used in other libraries.
yogthos/config takes the following approach for coercing environment variables:
The values are parsed using the following strategy:
[0-9]+
-> number^(true|false)$
-> boolean\w+
-> string- try parse as EDN, and return the original value as the default
tolitius/cprop does something similar for environment variables and system properties:
str->value will convert:
* numbers to longs
* alphanumeric values to strings
* true/false to boolean
* and will use Clojure reader for the rest
in case reader can't read OR it reads a symbol, the value will be returned as is (a string)
Thanks. I've looked into @yogthos's str->value
function:
(defn str->value
"ENV vars and system properties are strings. str->value will convert:
the numbers to longs, the alphanumeric values to strings, and will use Clojure reader for the rest
in case reader can't read OR it reads a symbol, the value will be returned as is (a string)"
[v]
(cond
(re-matches #"[0-9]+" v) (parse-number v)
(re-matches #"^(true|false)$" v) (Boolean/parseBoolean v)
(re-matches #"\w+" v) v
:else
(try
(let [parsed (edn/read-string v)]
(if (symbol? parsed) v parsed))
(catch Throwable _ v))))
I think this could just be simplified as: always a read as in, but when the result is a symbol, return the original string and in case of an error too?
Although:
user=> (conf/str->value "1M")
"1M"
I think in this case one would like to have 1M
instead of "1M"
.
I've put in place some automatic coercions now. Documented here:
https://github.com/babashka/cli/blob/main/API.md#auto-coerce