Как вызвать мультиметод по умолчанию из мультиметода - PullRequest
0 голосов
/ 01 мая 2018

Предположим, у меня есть мультиметод:

(defmethod print-method MyObject [obj writer] 
    (.write writer (format "%s %s" 
                           "prefix" 
                           (original-print-method-placeholder obj writer))

Я хочу выдать какую-нибудь произвольную строку, затем оригинальная строка, которая была бы сгенерирована, если бы я не определил print-method для этого объекта.

Итак, как мне вызвать "оригинал" print-method с этим объектом в качестве аргумента?

Ответы [ 2 ]

0 голосов
/ 01 мая 2018

В общем, вы можете использовать (.getMethod print-method :default), чтобы получить функцию по умолчанию, чтобы вы могли вызывать ее, хотя print-method вызывает *1003* сама, так что вы закончите переполнением стека. Может работать для других мультиметодов, в зависимости от их реализации.

Если вы хотите вариант print-method по умолчанию, вы можете обнаружить, что print-simple достаточно близко к тому, что вы хотите. (print-method функция по умолчанию вызывает print-simple.)

0 голосов
/ 01 мая 2018

ОК, поэтому из другого ответа я вижу, что вы, вероятно, имеете в виду clojure.core / print-method (я не знал, что существовало до этого).

Вы можете проверить это старое сообщение:

и не забудьте прочитать об иерархиях в случае, если они вступают в игру:


Обновление

Предположим, вы хотите напечатать ключевое слово. Оригинал print-method в clojure.core_print.clj:

(defmethod print-method clojure.lang.Keyword [o, ^Writer w]
  (.write w (str o)))

возможно, просто скопируйте и переименуйте источник, заменив оригинал defmethod своим собственным ( без Writer):

(defn print-method-kw [o]
  (str o))

(defmethod print-method clojure.lang.Keyword [o, w]
  (.write w (str "<kw " (print-method-kw o) " />")))

(println "look:")
(println :hello)

Результаты:

look:
<kw :hello />

Старый ответ на общие функции:

Просто запишите функцию перед определением мультиметода:

(def original-print-method-placeholder print-method)

(defmulti print-method ...)
(defmethod print-method ...)
(defmethod print-method ...)
(defmethod print-method ...)

Да, это работает:

(defn greeting [x] (str "Nice day, " x ))

(greeting "you") => "Nice day, you"

но позже в файле мы переопределим его:

(def orig-greeting greeting)  ; capture a reference to the function

(defmulti  greeting (fn [lang & args] lang))
(defmethod greeting :english [lang person]
  (str "(English accent) " (orig-greeting person)))
(defmethod greeting :french [lang person]
  (str "(French accent) " (orig-greeting person)))

(greeting :english "you")  => "(English accent) Nice day, you"
(greeting :french "you")   => "(French accent) Nice day, you"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...