Equivalent of Java's toString() for Clojure functions

你。 提交于 2019-12-08 15:58:56

问题


some Java code I'm using invokes toString() on my Clojure function objects, which return something like #<ns$something something.something$something@7ce1eae7>>- I want to return something else...presumably there's a way to include some metadata in the functions so their objects' toString() returns that instead ?


回答1:


If you just want to make the REPL print-out of your objects more meaningful, you can implement a defmethod print-method for the class in question.

Here's a shortened version of some code I've written recently; this makes the REPL print-out of a Selenium-WebDriver WebDriver object more meaningful:

(defmethod print-method WebDriver
[o w]
(print-simple
 (str "#<" "Title: "    (.getTitle o) ", "
           "URL: "      (.getCurrentUrl o) " >")
  w))

This prints out like #<Title: A Title, URL: http://example.com >

Here, WebDriver represents a class; you can just as easily do this for built-in Clojure data structures by implementing print-method for the appropriate class (The Joy of Clojure features a print-method for clojure.lang.PersistentQueue which has no nice representation by default). The o above is the actual object you're dealing with and w is a writer (required by these kinds of print functions).




回答2:


AFAIK, there's no simple way of doing this, though you can use reify or proxy to implement clojure.lang.IFn - which really just amounts to wrapping your function object in another object.

(def my-fn
  (let [f (fn [a] (println a))] 
     (reify clojure.lang.IFn
        (toString [this] "bla")
        (invoke [this a] (f a)))))


#'user/my-fn
user> my-fn
#<user$fn$reify__2903 bla>
user> (my-fn 2)
2
nil
user> (.toString my-fn)
"bla"
user> (str my-fn)
"bla"



回答3:


I don't think there's anything you can do about this: there's no way to ensure that your functions implement toString() differently without diving in and re-engineering the internals of Clojure.

However I think you can work around this problem quite easily - I'd suggest wrapping your functions within another class that you control (e.g. as defined through defrecord) before passing to Java code - then you will be able to provide your own custom toString() method, as well as get all the other advantages of using a record.



来源:https://stackoverflow.com/questions/5306015/equivalent-of-javas-tostring-for-clojure-functions

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!