Reputation: 3658
(pr +)
;=> #object[clojure.core$_PLUS_ 0x4e648e99 "clojure.core$_PLUS_@4e648e99"]
With more complex examples, this seems to be a consistent pattern:
#object[namespace$symbol addr "namespace$symbol@addr"]
What's the purpose of the third element here? When would it not follow this pattern?
Upvotes: 3
Views: 79
Reputation: 84369
This particular format is produced by the clojure.core/print-tagged-object
function (private to clojure.core
) which certain implementation of clojure.core/print-method
delegate to. Other implementations of print-method
don't use print-tagged-object
and produce different representations – for example Clojure's built-in data structures tend to be representable as Clojure literals.
The elements of the vector signify the following:
The first element is the class of the object.
Clojure functions are instances of classes whose names are derived from the namespaces they are defined in:
(class +)
;= clojure.core$_PLUS_
The second element is the identity hash code of the object as determined by
(System/identityHashCode x)
The final element is the result of calling print-method
on an ancillary value associated with the object, which for objects that use the #object[…]
representation will tend to boil down to a toString
call, although there are some exceptions:
(prn (atom {}))
;; #object[clojure.lang.Atom 0x565f390 {:status :ready, :val {}}]
(str (atom {}))
;= "clojure.lang.Atom@311bf055"
This particular behaviour is explained by this snippet from the implementation:
;; /src/clj/clojure/core_print.clj L410-411 (as of right now)
(defmethod print-method clojure.lang.IDeref [o ^Writer w]
(print-tagged-object o (deref-as-map o) w))
{:status :ready, :val {}}
comes from the deref-as-map
call; deref-as-map
is defined immediately above.
See the remainder of /src/clj/clojure/core_print.clj
for details (link to current tip of the master branch).
Upvotes: 5