如何从multimethod中调用默认的multimethod

时间:2018-04-30 23:20:41

标签: clojure

假设我有一个多方法:

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

我想发出一些arbirtary字符串,然后我没有为此对象定义print-method生成的原始字符串。

那么如何用这个对象作为参数调用“原始”print-method

2 个答案:

答案 0 :(得分:0)

好的,所以我从其他答案中看到你可能指的是clojure.core / print-method(我之前并不知道它存在)。

你可能想查看这篇旧帖子:

如果发挥作用,请不要忘记阅读层次结构:

更新

假设您要打印关键字。 print-method中的原始clojure.core_print.clj是:

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

也许只是复制&重命名源代码,将原始defmethod替换为您自己的( sans 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"

答案 1 :(得分:0)

一般情况下,您可以使用(.getMethod print-method :default)来获取默认功能,以便您可以调用它,尽管clojure.core的{​​{1}}会自行调用,因此您最终会堆栈溢出。它可能适用于其他多方法,具体取决于它们的实现。

如果您想要print-method的默认情况,您可能会发现print-method足够接近您想要的内容。 (print-simple的默认函数调用print-method。)