用于Clojure函数的Java的toString()等价物

时间:2011-03-14 23:52:23

标签: java clojure metadata tostring

我正在使用的一些Java代码在我的Clojure函数对象上调用toString(),返回类似#<ns$something something.something$something@7ce1eae7>>的东西 - 我想返回其他内容...大概有一种方法可以包含一些元数据函数使它们的对象'toString()返回它?

3 个答案:

答案 0 :(得分:12)

如果您只想让对象的REPL打印输出更有意义,可以为相关课程实现defmethod print-method

这是我最近编写的一些代码的缩短版本;这使得Selenium-WebDriver WebDriver对象的REPL打印输出更有意义:

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

这打印出#<Title: A Title, URL: http://example.com >

这里,WebDriver代表一个类;您可以通过为适当的类实现print-method来轻松地为内置Clojure数据结构执行此操作(Clojure的Joy为print-method提供clojure.lang.PersistentQueue,默认情况下没有很好的表示)。上面的o是您正在处理的实际对象,w是一个编写者(这些打印函数需要)。

答案 1 :(得分:11)

AFAIK,没有简单的方法可以做到这一点,尽管你可以使用reify或proxy来实现clojure.lang.IFn - 这实际上只相当于将你的函数对象包装在另一个对象中。

(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"

答案 2 :(得分:1)

我认为你无法做到这一点:没有办法确保你的函数以不同方式实现toString(),而不会潜入并重新设计Clojure的内部结构。

但是我认为你可以很容易地解决这个问题 - 我建议在传递给Java代码之前将你的函数包装在你控制的另一个类中(例如通过defrecord定义) - 然后你就可以了提供自己的自定义toString()方法,以及获得使用记录的所有其他优点。