Perhaps because of the name places its api doc next to the other namespace functions, the main docs being in alphabetical order. Obviously thereβs the cheatsheet nowadays.
(defn handle-args
"Handle your program arguments here. You may support zero or more.
Ensure that you use the exit function when processing is complete."
[config {:keys [options arguments]}]
(if (seq arguments)
(if (= 1 (count arguments))
[0 ["there is 0 arguments"]]
[0 ["> 1 argument"]])
[0 ["No argument handler"]]))
Can someone explain me
[0 ["string here"]]
meaning. This is a template name lein-bin. handle-args
function is call in main
fuction. It is also the entry where we put something we want to work in cli here. I can understand the abstraction layer. But the syntax is strange. Why we need ["a number" ["code"]]
in here. It put directly "code"
it will not work. What is the meaning of those numbers?What is the function that calls handle-args
doing with the return value?
(defn run
"Processing starts here. Use this function when running from a REPL.
The help option and any errors are handled here. Otherwise, processing
is passed to the argument handler."
[& args]
(let [config (configure)
{:keys [options arguments errors summary] :as opts}
(-> (parse-opts args (:cli config))
check-options
(update-in [:options] merge logging-options)
configure-logging)]
(cond
(:help options) (exit 0 (usage config summary))
errors (exit 1 (error-msg config errors))
:else (let [[exit-code message] (handle-args config opts)]
(exit exit-code message)))
))
handle-args being called from here(defn -main
"Entry point for command-line processing. This will be used when running outside of a REPL."
[& args]
(System/exit (apply run args)))
And run being called from hereThis line of code (let [[exit-code message] (handle-args config opts)]
is using a Clojure syntax for something called "destructuring". Are you familiar with that?
If not, I can explain it.
Ah, thank you. Can you give me some good document url. I can learn by myself. I should not waste your time
No worries. The quick explanation is that when you do (let [[a b c] (some expression here)] ...)
, it calls (some expression here)
, gets the return value, and as long as that return value is a sequence kind of thing (either a list, a vector, or a sequence), then a
is bound the first element, b
to the second, and c
to the third. Any remaining elements are ignored in that expression.
Here is a link to an article on http://clojure.org with many other things destructuring can do, but you might want to focus on the part for sequence destructuring and save the parts that can take apart maps for later when you need it: https://clojure.org/guides/destructuring
ah. So num
in this case is exit-code
wow. Thank you very much.
So the symbol exit-code
is bound to that first element, which are the numbers 0 in the sample code you pasted earlier. Those are passed to the function exit
, which probably passes it to the Java method System/exit, and that becomes the exit status when the process exits, which some ways of invoking a program pay attention to to see if an error occurred (convention is 0 for all OK, non-0 for some kind of error).
The symbol message
is bound to the second element, which in your example is a vector of one string. I don't know exactly what exit
is doing with that vector, probably printing the string somehow.
`(defn exit [exit-code message]
(if (= 0 exit-code)
(apply infoc message)
(apply errorc message))
exit-code)
ah, I can find defn of exit
here. Thank you very much
infoc
and errorc
is import from other package
Is there still a use case for definterface
or should I always use defprotocol
instead?
Joy of Clojure, 2nd ed. (p. 302-304) mentions primitive arg types and return values as the primary advantage of definterface.
Has that changed over they years?
https://corfield.org/blog/2013/05/01/instrumenting-clojure-for-new-relic-monitoring/ @jumar That is probably the only time I've used definterface
and deftype
myself...
Cool, thanks for the example!
Oh, and in next.jdbc
...
https://github.com/seancorfield/next-jdbc/blob/develop/src/next/jdbc/result_set.clj#L440 I use it as a marker for disambiguating printing.
I think that's still accurate.
In that protocol functions are always boxed and can't be made primitive.
As far as I know they still don't support primitives, so if you do need that definterface can be an alternative
Though I'm not sure if proxy or reify can generate primitive types, but I guess if the book says so
that's true, and one thinks of it as a thing you're doing to a namespace
@jumar definterface
can be useful if you want to provide a marker type, i.e. an interface for the sole purpose of being able to say (instance? Marker foo)
see e.g. core.match where this is used
quick question - a project that is set up with lein - is there a simple way of updating the documentation based on the project.clj
?
it might be that the answer is no -
Good evening. I'm trying to look up an old post by Stuart Sierra where he argues for something along the lines of > it's better to have a broad API with many functions that's possibly difficult to understand than a narrow API that hasn't been battle-tested, and that might not have what I need. Digging through his blog now, https://stuartsierra.com/blog/page/26, haven't found it yet. Any advice?
@vemv thanks a lot! π
https://clojurians.slack.com/archives/C03S1KBA2/p1611087986264200?thread_ts=1611085678.261200&cid=C03S1KBA2 @grazfather Care to elaborate? I've begun reading that book, and I'm enjoying it so far. To me, it rhymes with a lot of what Rich said in The Language of the System, and the principles behind namespace-qualified keywords.
specifically, I think he mentions that he often prefers to use a big java package directly, rather than going through a Clojure wrapper that might just cover certain parts.
Is there a tool that allows generation of a spec based on sample data (as a starting point to further refine the spec)? Asking here because searching the terms "generate spec" are all about s/gen
, and I don't see such a thing in the toolbox
exactly this! π
I disagree. and I think that most would. Peek at "the philosophy of software design"
having a narrow api that only indirectly gives you access to an underlying platform sounds a lot like https://en.m.wikipedia.org/wiki/Inner-platform_effect
Did you have a look to available plugins in leiningen https://github.com/technomancy/leiningen/wiki/Plugins#documentation . Gargamel or codoc, depending on what you are looking for.
I like the adage, βmake the common case easy and the complex case possibleβ since itβs all too common for libraries to do neither
ah this q is for me - I'm quite a big S. Sierra fan :) https://stuartsierra.com/2013/07/28/the-amateur-problem
Hi there, does anybody know an alternative to https://github.com/jebberjeb/specviz? I would like to see my model in a nice graphical format and I wonder what I can use.