2

私はこのしつこい問題を抱えています:

ラッパーは、関数を受け取り、パラメーターを受け取る別の関数を返し、パラメーターに対して何かを行い、それを関数に戻す関数です。

(defn ラッパー [関数]
  (fn [パラメータ]
    (func (do-something-to params))))

私がやりたいのは、ラッパーからラッパーへのパラメーターの変更を追跡することです

たとえば、次の 2 つのラッパーを定義できます。

(defn wrap-inc [関数]
  (コンプ機能株式会社))

(defn wrap-double [関数]
  (comp 関数 #(* % 2)))

それから、

(定義 h (-> #(* % 3)
       ラップ株式会社
       ラップダブル))

次と同等です。

(def h (fn [x] (* (inc (* 2 x)) 3)))
(時間 1) => 9

dbg->今、私はそのように定義したいと思います

(def h-dbg (dbg-> #(* % 3)
                  ラップ株式会社
                  ラップダブル))

同じ機能を引き続き提供するだけでなく、古い値と新しい値も追跡します。

(h-dbg 1) => 9

コンソールにデバッグ情報も表示されます。

"wrap-double: (in: 1, out: 2)"
"wrap-inc: (in: 2, out 3)"

この種のパターンは、このようなリング ラッパーをデバッグして、それぞれが何をしているかを把握するのに非常に役立ちます。たとえば、次の典型的な例です。

(定義開始 []
  (桟橋/ラン桟橋
   (-> #'routes-handler
       ;;(wrap-reload-modified ["clj-src"])
       (ラップファイル「リソース/パブリック」)
       ラップファイル情報
       wrap-decamelcase-params
       ラップキーワードパラメータ
       ラップネストされたパラメータ
       ラップパラメータ
       wrap-ignore-trailing-slash) {:ポート 8890 :join? 間違い}))
4

3 に答える 3

2

writer モナドと呼ばれるものを探していると思います。

ここに Writer モナドのわかりやすい説明と、実際の動作例がいくつかあります (残念ながら、これは Haskell のものです)。

基本的に、このモナドは、「通常の」出力に加えてログ値を返す関数を作成するのに役立ちます。たとえば、次のタイプの関数があるとします。

f :: a -> (b, l)
g :: b -> (c, l)

writer モナドを使用してそれらを構成し、次の型の新しい関数を取得できます。

h :: a -> (c, l)

警告: Clojure マクロ->とは、合成->>に使用する必要があるため、モナド関数を合成するときにまったく同じ方法で使用することはできませんbind

別の解決策として、副作用のあるラッパーを使用できます。

(defn wrapper
  [f]
  (fn [& params]
      (print params) ;; or some other logging operation
      (apply f params)))

これが機能するのは、関数本体の最後の式の値が戻り値であるためです。前の式が評価され、その結果が破棄されます。

于 2012-09-11T13:18:06.967 に答える
0

手っ取り早い方法は、それをマクロに詰め込むことです...この実装は、単一値の引数を持つ関数のみを実行します。

(defn wrap-print [f]
  (fn [&args]
    (print "->"(second(re-find# "\ $(。*)@"(str f)))args)
    (f argsを適用)))

(-> 3((wrap-print inc))((wrap-print dec)))
;; => "-> inc(3)-> dec(4)"

(defmacro dbg-> [n&funcs]
  (println "")
  (印刷n)
  (let [wfncs(map#(list(list wrap-print%))funcs)]
     `(->〜n〜@ wfncs)))

(dbg-> 3 inc dec)
;; => "3-> inc(3)-> dec(4)"

于 2012-09-13T00:05:01.477 に答える
-1

Maybe add-watch can help you doing this.

The limitation is you can only watch references(atom/ref/var/agent).

于 2012-09-11T00:32:50.020 に答える