clojure/clojure — pull request #48 by nurkiewicz (2014-04-18 22:09:59+00:00)
Title: Add transient keyword to cached toString() value in _str.

`_str` field in `Keyword` and `Symbol` classes lazily caches result of `toString()`. Because this field is not `transient`, serializing (using Java serialization) any keyword before and after calling `toString()` for the first time yields different results:

(import (java.io ByteArrayOutputStream ObjectOutputStream
ByteArrayInputStream ObjectInputStream))

(defn- serialize [obj]
(with-open [bos (ByteArrayOutputStream.)
stream (ObjectOutputStream. bos)]
(.writeObject stream obj)
(-> bos .toByteArray seq)))

(def s1 (serialize :k))
;(println :k)
(def s2 (serialize :k))
(println (= s1 s2))

Uncomment `(println :k)` and suddenly `s1` and `s2` are no longer equal.

This issue came up when I was trying to use keywords as key in [Hazelcast](https://github.com/hazelcast/hazelcast) map. Hazelcast uses serialized keys in various scenarios, thus if I first put something to map under key `:k` and then print `:k`, I can no longer find such key.