Fork me on GitHub
#clojure
<
2018-11-01
>
cddr01:11:27

I have a multi-method and a corresponding defmethod that should kick when the method is passed an object like {:type :mock ...}.

(defmulti transport (fn [config]
                       (println "dispatching transport: " config)
                       (:type config)))

(defmethod t/transport :mock
  [{:keys [driver topics]}]
  ...
  )
I'm pretty sure I'm passing it an object with the right :type. And in the ns, there's a require on the namespace that defines the mock defmethod. This is a test ns. When I run it on it's own, it behaves as expected but when run as part of an entire suite, it behaves like the required defmethod hasn't been loaded yet. Any tips on how to track the problem down?

cddr12:11:05

Turns out there was a duplicate ns that was overriding the one I needed due to a prior copy-paste error.

hiredman01:11:13

you likely have a :reload-all somewhere in your test suite

hiredman01:11:46

well, no because defmulti acts like defonce in that case, but something like that would be my first guess

hiredman01:11:59

any kind of code reloading

hiredman01:11:37

or maybe you are using namespaced keys and :: or something

hiredman01:11:06

you can check the identity of t/transport at load time by putting something like (println t/transport) after the multimethod, and then (println t/transport) again when the tests actually run

hiredman01:11:23

you can see what methods are defined on the multimethod using get-methods

cddr01:11:02

Yeah figured that might be the case. Thanks for the tips.

seancorfield01:11:49

@cddr One trick is to add (def transport nil) immediately above the defmulti -- and that will force the defmulti to be reapplied when you reload the ns.

michael zhou08:11:28

Hello, I am having trouble when I use hugsql to get a map.

lukas.rychtecky08:11:20

I’d guess that’s not related to HugSQL itself. I think you require somewhere coercing function that converts Date into JodaTime (This happen in JDBC layer).

mping14:11:14

probably clj-time.jdbc

michael zhou08:11:49

I just want the date. Who can tell me why? thanks.

henrik09:11:40

Check out https://github.com/clj-time/clj-time to deal with date objects.

isaac09:11:03

clojure compile not emit clojure.tools.reader.reader_types.Reader.(my dep tree com.taoensso/carmine -> com.taoensso/encore -> org.clojure/tools.reader)

isaac09:11:36

Caused by: java.lang.ClassNotFoundException: clojure.tools.reader.reader_types.Reader

ampersanda10:11:40

Hi! I am just starting to learn clojure.java.jdbc and postgresql in Clojure language, and I am stuck that when I am trying to update my data inside database, it just throw an error which “org.postgresql.util.PSQLException This ResultSet is closed.” Below is my code for update

(sql/execute! db ["UPDATE public.\"user\" SET user_last_login = to_timestamp(?), user_token = ? WHERE user_email = ?" (str timestamp) token email])
I also try this
(sql/update! db "public.\"user\"" {:user_last_login (str "to_timestamp(" timestamp ")") :user_token token} ["user_email = ?" email])
and I don’t know what to do, please help, thank you. Pardon my English

athomasoriginal13:11:45

I am printing the following to my terminal:

(defn my-data 
    []
    '({:first  "Dan" :last "Smith"}))

(println my-data)
When this is logged to the console, the double-quotes are not preserved. Is there a way to have them preserved in the terminal? (A REPL would do this but lets assume, for the sake of argument, I can only println to a terminal window)

lukas.rychtecky13:11:02

(println (pr-str (vector {:first "Dan" :last "Smith"}))

schmee13:11:31

user=> (pr '({:first  "Dan" :last "Smith"}))
nil
({:first "Dan", :last "Smith"})

seancorfield15:11:46

@ampersanda There's a #sql channel which is a lot quieter than this one -- easier to get SQL/JDBC answers there. I've pretty sure your second one won't work since you're passing a literal string as the value of :user_last_login (but I'd expect a different error).

ampersanda02:11:41

Okay, thank you for your reply :)

seancorfield15:11:08

If you can share more of your code in #sql and more of the exception you are seeing, that might help us to help you.

dangercoder16:11:42

Anyone who's using CLJ-HTTP who knows if it's possible to hand it a SSLContext somehow?

dangercoder16:11:29

Seems like changing the builders setting seems to do the trick.aka setSSLSocketFactory

dangercoder16:11:35

Using :http-builder-fns hmm..

lwhorton17:11:56

im digging into ways to write an extensible library via multimethods/protocols. this is my first real foray into this area of clojure, and i’m having a conceptual issue. if i have a type Foo implementing protocol ABC, is there a way to extend-type Foo ABC such that I can provide some custom protocol fn implementation, but not all implementations (where not providing an override implementation will fall back to the original type’s impl)?

lwhorton18:11:40

or is that generally discouraged because it’s too “classy/inheritance” based?

lwhorton18:11:56

(defprotocol Test1 (-to-handler [dsl]) (-to-handler-2 [dsl]))

(deftype DefaultHTTP [dsl] 
  Test1
   (-to-handler [_] #{dsl})   
   (-to-handler-2 [dsl] [dsl]))

(deftype MyHTTP [dsl]
  Test1 
  (-to-handler [_] (-to-handler (DefaultHTTP. dsl)))  ;; <= can this be avoided?
  (-to-handler-2 [_] '(dsl)))

mpenet20:11:28

You can hack something around extend to do that, since it deals with maps of fns. Values all the way down

noisesmith18:11:20

no, that doesn't exist - this intentionally isn't inheritance in that way

lwhorton18:11:12

> this intentionally isn’t inheritance can you point me in the right direction with respect to why this is a bad idea?

noisesmith18:11:23

you can get these symantics by having multiple multimethods (one for each method) with :default implementations

noisesmith18:11:08

@lwhorton I don't have the best link at my fingertips, but it's a clojure design decision to avoid java's native inheritence semantics, so you either get interfaces without default methods, or multimethods which do not reflect a native java feature

lilactown18:11:43

yep. I just recently “discovered” this same pattern when trying to think of a way to allow lib consumers to define custom keywords in a hiccup parser: https://github.com/Lokeh/hx/blob/master/src/hx/hiccup.cljs

lilactown18:11:26

the other thing you can do is pass in the actual implementation into the type constructor, and provide some higher-level functions with sane defaults for people who don’t care about the details

noisesmith18:11:22

yes, you can manage about the right behavior with a hash-map full of functions that take an object as their first arg and merge / assoc for inheritance

cddr18:11:31

In visualvm, all clojure repl's appear by default as "Clojure application". How would one get a project specific value to show up here?

noisesmith18:11:55

by defining your own main method that launches a clojure repl - what's shown is the main method that is running in the vm

noisesmith18:11:06

it would be a very small java program, but also it would be relatively pointless - the only advantage would be custom strings in jvm tooling, and there's multiple ways you could do it wrong

hiredman18:11:18

supposedly -Dvisualvm.display.name=MyProgram works

cddr18:11:04

Yep. Found that. Trying to see how to give it spaces but that's good enough.

noisesmith18:11:39

oh, fun trick

roklenarcic21:11:09

Hm if I have two records that refer to each other, how do I declare them

roklenarcic21:11:22

clojure is touchy about order of declarations

roklenarcic21:11:23

(defrecord A .... uses ->B) and (defrecord B [^A parent])

andy.fingerhut21:11:26

How were you hoping to create a cycle between two immutable data structures via direct references? I don't know how to do that.

andy.fingerhut21:11:46

i.e. I think that is impossible.

roklenarcic21:11:37

No no... record A has a function that creates instances of B

roklenarcic21:11:43

and it selfinserts

andy.fingerhut21:11:49

If you weren't planning to do that, then perhaps defining defrecord A first, then B, but before A put something like (declare ->B) may work.

roklenarcic21:11:29

Tried declare it seems something breaks: CompilerException java.lang.ClassCastException: clojure.lang.Var cannot be cast to java.lang.Class, compiling:(introspect.clj:78:1)

noisesmith21:11:00

instead of using ->B directly you can forward declare and call a function that calls ->B

roklenarcic21:11:04

since the method in A using B is protocol implementation I guess I could implement protocol for record lower

noisesmith21:11:01

also, why not hint the protocol(s) that B implements instead of hinting B itself?

noisesmith21:11:08

(if hinting is even needed...)

roklenarcic21:11:55

I'll just use extend-type to add implementations later in code

genmeblog22:11:21

already asked on #beginners but maybe here is better place. I want to create an instance of the Java inner class which is not static.

genmeblog22:11:39

ok, solved (compiler inserts additional parameter, outer class object, to the constructor)