Эквивалентный toString () Java для функций Clojure - PullRequest
9 голосов
/ 15 марта 2011

некоторый Java-код, который я использую, вызывает toString() для моих объектов функций Clojure, которые возвращают что-то вроде #<ns$something something.something$something@7ce1eae7>> - я хочу вернуть что-то еще ... предположительно, есть способ включить некоторые метаданные в функции, чтобы ихtoString() объектов возвращает это вместо?

Ответы [ 3 ]

12 голосов
/ 15 марта 2011

Если вы просто хотите сделать распечатку REPL своих объектов более значимой, вы можете реализовать defmethod print-method для рассматриваемого класса.

Вот сокращенная версия некоторого кода, который я написалотносительно недавно;это делает распечатку REPL объекта Selenium-WebDriver WebDriver более значимой:

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

Это печатает как #<Title: A Title, URL: http://example.com >

Здесь WebDriver представляет класс;Вы можете также легко сделать это для встроенных структур данных Clojure, реализовав print-method для соответствующего класса (Joy of Clojure имеет print-method для clojure.lang.PersistentQueue, который по умолчанию не имеет удобного представления).o выше - это реальный объект, с которым вы имеете дело, а w - писатель (требуется для этих функций печати).

11 голосов
/ 15 марта 2011

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"
1 голос
/ 15 марта 2011

Я не думаю, что с этим можно что-либо сделать: нет способа гарантировать, что ваши функции по-разному реализуют toString (), не погружаясь и не изменяя внутреннюю структуру Clojure.

Однако я думаю,вы можете обойти эту проблему довольно легко - я бы предложил обернуть ваши функции в другой класс, которым вы управляете (например, как определено в defrecord ), прежде чем переходить к коду Java - тогда вы будетебыть в состоянии предоставить свой собственный метод toString (), а также получить все другие преимущества использования записи.

...