Sean Allred
Sean Allred

Reputation: 3658

What are the different parts in (pr raw-object)?

(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

Answers (1)

Michał Marczyk
Michał Marczyk

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:

  1. 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_
    
  2. The second element is the identity hash code of the object as determined by

    (System/identityHashCode x)
    
  3. 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

Related Questions