'Turn off *print-namespace-maps* in repl
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.
Solution 1:[1]
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))
Solution 2:[2]
Using (set! *print-namespace-maps* false) works for me. (But this is some 5 years later.)
This also works, and can sometimes be more desirable:
(binding [*print-namespace-maps* false]
(pr-str {:a/foo 1 :a/bar 2}))
=> "{:a/foo 1, :a/bar 2}"
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | madstap |
| Solution 2 | PEZ |
