Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Turn off *print-namespace-maps* in repl

Tags:

clojure

With Clojure 1.9-beta2, the reader and writer now support a compact syntax for maps. The syntax avoids repeating the namespace in the case where all the keys are qualified keywords with the same namespace:

> (pr-str {:a/foo 1 :a/bar 2})
"#:a{:foo 1, :bar 2}"

That causes problem when sending such a serialized map to a Clojure 1.8 process: the old reader running there will fail to read it and throw a java.lang.RuntimeException: Reader tag must be a symbol.

Luckily, the printer only does this when the dynamic variable *print-namespace-maps* is truthy, and it's falsey by default, so my app continues to work in production. However, the REPL sets it to true, so when I work in the REPL and do something that ends up sending a request to a Clojure 1.8 service, it fails. How can I disable the new syntax in the REPL also?

I thought that maybe I could just (set! *print-namespace-maps* false) in my repl or add {:user {:repl-options {:init (set! *print-namespace-maps* false)}}} to my ~/.lein/profiles.clj, but that doesn't seem to work. I think the reason may be that the REPL uses binding to create thread-local bindings for a bunch of variables including this one, and set! does not work for local variable bindings.

like image 464
Vebjorn Ljosa Avatar asked Oct 20 '17 17:10

Vebjorn Ljosa


1 Answers

You can redefine print-method for maps, which should work regardless of environment.

(defmethod print-method clojure.lang.IPersistentMap [m, ^java.io.Writer w]
  (#'clojure.core/print-meta m w)
  (#'clojure.core/print-map m #'clojure.core/pr-on w))
like image 92
madstap Avatar answered Nov 10 '22 04:11

madstap