Skip to content

Instantly share code, notes, and snippets.

@Chouser
Created October 1, 2013 18:56
Show Gist options
  • Save Chouser/6783292 to your computer and use it in GitHub Desktop.
Save Chouser/6783292 to your computer and use it in GitHub Desktop.
prevent infinite print recursion for IDeref
;; As originally posted, circa July 2009: http://web.archive.org/web/20110919081924/http://paste.lisp.org/display/83647
(def *iderefs* #{})
(defmethod print-method clojure.lang.IDeref [o #^Writer w]
(if (*iderefs* o)
(.write w (format "#<%s@%x>"
(.getSimpleName (class o))
(System/identityHashCode o)))
(binding [*iderefs* (conj *iderefs* o)]
(print-sequential (format "#<%s@%x: "
(.getSimpleName (class o))
(System/identityHashCode o))
pr-on, "", ">"
(list (if (and (future? o) (not (future-done? o)))
:pending
@o))
w))))
;; === without 'future' support ===
(def *iderefs* #{})
(defmethod print-method clojure.lang.IDeref [o #^Writer w]
(if (*iderefs* o)
(.write w (format "#<%s@%x>"
(.getSimpleName (class o))
(System/identityHashCode o)))
(binding [*iderefs* (conj *iderefs* o)]
(print-sequential (format "#<%s@%x: "
(.getSimpleName (class o))
(System/identityHashCode o))
pr-on, "", ">", (list @o), w))))
;; === manual binding scope, without future ===
(def *iderefs* #{})
(defmethod print-method clojure.lang.IDeref [o #^Writer w]
(if (*iderefs* o)
(.write w (format "#<%s@%x>"
(.getSimpleName (class o))
(System/identityHashCode o)))
(do
(try
(set! *iderefs* (conj *iderefs* o))
(catch IllegalStateException e))
(print-sequential (format "#<%s@%x: "
(.getSimpleName (class o))
(System/identityHashCode o))
pr-on, "", ">", (list @o), w))))
user=> (binding [*iderefs* #{}]
(let [a (atom :a)
b (atom :b)]
(reset! b a)
(reset! a b)
(prn [a b])))
[#<Atom@78467991: #<Atom@5ad75c47: #<Atom@78467991>>> #<Atom@5ad75c47>]
nil
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment