clojureclojureclr

reify, ToString


Probably obvious, but given this code (from http://clojure.github.com/clojure/clojure.core-api.html#clojure.core/reify):

(defn reify-str []
  (let [f "foo"]
    (reify Object
      (ToString [this] f))))

(defn -main [& args]
  (println (reify-str))
  (System.Console/ReadLine))

Why am I getting this output?

#<ui$reify_str$reify__4722__4727 foo>

Instead of:

foo

I'm running ClojureCLR in Windows, if it helps. Thanks!


Solution

  • Your basic problem is that the Clojure REPL uses print-method, not .toString. You have to define print-method for your type. It's a little bit annoying for reified types since it makes them kind of verbose. You'll have to do something like this:

    (defn reify-str []
      (let [f "foo"
            r (reify Object
                (ToString [this] f))]
        (defmethod clojure.core/print-method (type r) [this writer] 
          (print-simple f writer))
        r))
    

    (I've only tested this in vanilla Clojure, but I think it's the same in ClojureCLR.)

    At this point, though, you're almost better off creating an actual type instead of reifying, because you're redefining the method every time. (I guess you could do some sort of global state to avoid the necessity, but…well, you can see why defining a type might be preferable.)