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