Clojure本身不提供任何可靠的建議功能,甚至通過def
/defn
定義的功能。請看下面的例子:
(require '[richelieu.core :as advice])
(advice/defadvice add-one [f x] (inc (f x)))
(defn func-1 [x] x)
(def func-2 func-1)
(advice/advise-var #'func-1 add-one)
> (func-1 0)
1
> (func-2 0)
0
形式(def func-2 func-1)
,VAR func-2
的評估後,將含有 VAR func-1
(換句話說,它的價值)的結合,所以advice-var
不會影響它。
Eventhough,像func-2
定義是罕見的,你可能已經注意到或使用下列內容:
(defn generic-function [generic-parameter x y z]
...)
(def specific-function-1 (partial generic-function <specific-arg-1>))
(def specific-function-2 (partial generic-function <specific-arg-2>))
...
如果你的建議generic-function
,沒有具體的功能將工作,由於上述特點符合市場預期。
如果建議是你的關鍵,因爲這可能工作,我想一個解決方案如下:因爲Clojure的功能被編譯成Java類,您可以嘗試replace java methodinvoke
與曾期望行爲的其他方法(然而,當談論替換協議/接口方法時,事情變得更加複雜:似乎你將不得不在每個實現特定協議/接口的類中替換所需的方法)。
否則,您需要爲每個想要建議的函數顯式包裝。在這種情況下宏可能有助於減少樣板。