Hi, does anyone know of a nice solution for validating a pre-defined spec (using s/keys
) on the metadata of a value?
For context, I'm trying to provide s/fdef
with an :args
argument that says "This value should have metadata conforming to the following spec ::foo
".
It seems transit is giving an NPE instead of a meaningful error message when using :handlers
and you give it a type it can't handle:
(defn write-transit [v]
(let [baos (java.io.ByteArrayOutputStream.)]
(transit/write (transit/writer baos :json {:handlers {java.time.LocalDateTime ldt-write-handler}}) v)
(.toString baos "utf-8")))
(write-transit (into-array String ["foo"]))
Syntax error (NullPointerException) compiling at (/tmp/transit.clj:19:1).
null
I'll make an issue for it: https://github.com/cognitect/transit-clj/issues/50
And another question: https://ask.clojure.org/index.php/10617/generic-way-to-de-serialize-arrays-using-transit
And another issue: https://github.com/cognitect-labs/test-runner/issues/29 Also provided a solution proposal: https://github.com/cognitect-labs/test-runner/pull/30
This might be a terrible question... but is it bad form to perform any I/O (like db query) in the dispatch fn of a multimethod?
I think the big question is how does the dispatch function get its db connection
in general, a defmulti is a top level form, and the dispatch function only gets the arguments to the defmulti
so either 1. the database connection is an argument to the defmulti, or 2. you have the database connection def'ed somewhere and the dispatch function refers to it
#2 is gross
@jmckitrick Not any more bad form than any other function
<http://clojure.java.io|clojure.java.io>
uses a multimethod for the copy function and that does IO
ohhhh wait
you mean for the determining the implementation to call
i don't think it is often done, but i still think its neither better or worse than doing IO in a regular function
very curious the usecase though
it feels like doing a db call in a getter in a C-like language. it's not only messy (where is the db connection coming from?), but hides a potential area of slowdown and side effects by hiding the db call in the defmulti
instead of exposing it directly in either the calling location or the defmethod
I thought the value I needed was in the one map I was passing to the multimethod, but now I see it's a different map, from a different query. I could just add the map as an extra arg to the multimethod, but that makes it ugly. But now that I think about it... it actually makes sense. So the simplest solution might be the best.
I have a "stupid" problem with clojure deps. I have a couple of alias defined. Now some I have to call with "clojure -X:alias" and others with "clojure -M:alias". I can remember the names of my aliases (cljfmt, lint, release, test, etc). But I dont remember how I did set them up. I understand the difference, but I dont uderstand why there cannot be just one way to execute an alias. The alias knows if it would use a main function or if it would call the function directly.
@hoertlehner a task runner like the one in babashka can solve this problem (at least it does so for me): https://book.babashka.org/#tasks
Thanks!
Seems like I am not the only one with bad memory
as far as why, it's because the arguments are interpreted differently
thanks!
But if I have no args at all
then it shouldnt matter
is it possible to switth all -M aliases to -X aliases
I guess this would solve my issue also
just some time to look into the namespaces to find the right fucton names I guess
the thing being passed to -M or -X is a argument
-M is launching via clojure.main, sort of the classic launch, it used to be (maybe still is supported but is deprecated) that you got this behavior if you didn't specify a flag at all
-X is launching via the new fn/args mechanism