James, I was surprised myself that I knew the answer. I had a guess as to the origin of this information so I Googled to confirm. The problem was mentioned in one of the Java Puzzlers [1] talks [2] by Joshua Bloch and Bob Lee. The same issue was also discussed on Stack Overflow [3] (which I discovered in the process of the aforementioned Googling).
[1] http://www.javapuzzlers.com/ [2] http://strangeloop2010.com/system/talks/presentations/000/014/450/BlochLee-JavaPuzzlers.pdf?1290462274 - See puzzle #5 [3] http://stackoverflow.com/questions/8630279/why-cant-i-hold-enummap-entries-via-a-for-loop-even-if-i-use-final-best-w Thanks, Elias. On Thursday, October 3, 2013 5:29:24 AM UTC-4, James Warren wrote: > > Thank you for your responses, Marek and Elias. > > Elias, you hit it square on the head - I was using Java 6, and changing to > Java 7 corrected the issue. If you don't mind me asking, how did you even > know about this behavior? This isn't the type of information you typically > see on Hacker News, albeit much more helpful! :) > > On Wednesday, October 2, 2013 7:17:40 PM UTC-7, Elias Zaretsky wrote: >> >> Are you using Java 6 by any chance? This issue may be due to a gotcha in >> java.util.EnumMap. The implementation of the entry set iterator in EnumMap >> in Java 6 is unorthodox [1]. Its next() method always returns the same >> object, which is mutated to "point" to different entries in the map as the >> iterator moves forward. This explains the behavior you are observing. Try >> switching to Java 7 or make sure you call the keys function every time you >> need the sequence of keys. >> >> [1] >> http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/EnumMap.java#EnumMap.EntryIterator >> >> Thanks, >> Elias. >> >> On Wednesday, October 2, 2013 5:19:31 PM UTC-4, James Warren wrote: >>> >>> I've been using Clojure for a couple months, so while I feel comfortable >>> with it, I'm not certain whether some unusual behavior I encountered is a >>> bug or a lack of understanding on my part. (I suspect the latter.) >>> >>> The context arose from using Clojure reflection to inspect a class >>> generated by Apache Thrift <http://thrift.apache.org>. Such classes >>> have a static, unmodifiable map describing the members of the class. I >>> wrote a function to extract the keys of this map; it initially appears to >>> work, but "def"ing the results to a symbol and repeatedly using that symbol >>> returns inconsistent results. >>> >>> I've boiled it down to a smaller example that replicates the result: (gist >>> available <https://gist.github.com/jameswarren/6799309>) >>> >>> // Java class >>> >>> public class DummyClass { >>> public enum DummyEnum { >>> FIRST, SECOND, THIRD >>> } >>> >>> public static final Map<DummyEnum, String> dummyMap; >>> static { >>> Map<DummyEnum, String> tmpMap = new EnumMap<DummyEnum, >>> String>(DummyEnum.class); >>> tmpMap.put(DummyEnum.FIRST, "first"); >>> tmpMap.put(DummyEnum.SECOND, "second"); >>> tmpMap.put(DummyEnum.THIRD, "third"); >>> dummyMap = Collections.unmodifiableMap(tmpMap); >>> } >>> } >>> >>> // Clojure ns >>> >>> (ns refbug.core >>> (:import [refbug DummyClass])) >>> >>> (defn foo [^Class c] >>> ;; note: (into [] (keys (clojure.lang.Reflector/getStaticField c >>> "dummyMap")))) works >>> (keys (clojure.lang.Reflector/getStaticField c "dummyMap"))) >>> >>> (def m (foo DummyClass)) >>> (println m) >>> ;; (#<DummyEnum FIRST> #<DummyEnum SECOND> #<DummyEnum THIRD>) >>> (println m) >>> ;; (#<DummyEnum THIRD> #<DummyEnum THIRD> #<DummyEnum THIRD>) >>> >>> Two different values upon successive calls using m. Is this expected? And >>> if so, why? >>> >>> Many thanks, >>> -James >>> >>> -- -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.