Search code examples
stringclojurescript

Convert custom type into string


Given a custom datatype in Clojurescript:

(deftype Foo [bar])

I would like to be able to convert this type into a string using the str macro. The result of (str (->Foo "bar")) is always "[object Object]". Browsing through various docs and sources I found the IPrintWithWriter protocol that allows me to define a custom string representation. So the following extension is very close to what I'm looking for:

(extend-type Foo
  IPrintWithWriter
  (-pr-writer [this writer _] (-write writer (str "test:" (.-bar this)))))

Indeed, when using (pr-str (->Foo "bla")) the return value is indeed the string "test:bla". However, the return value of str stays "[object Object]".

How can I supply a custom string representation of Foo for str instead of for pr-str?


Solution

  • ClojureScript's str uses Object.toString method of the object passed as its argument:

    (str x) returns x.toString()

    You can override this method for your Foo type:

    (deftype Foo [bar]
      Object
      (toString [this]
        (str "Test: " bar)))
    ;; => cljs.user/Foo
    
    (str (->Foo "x"))
    ;; => "Test: x"