【问题标题】:debugging wrapped functions in clojure在 clojure 中调试包装函数
【发布时间】:2012-09-03 20:21:02
【问题描述】:

我有这个烦人的问题:

包装器是接受一个函数的函数,并返回另一个接受参数的函数,对参数执行某些操作并将其粘贴回函数中。

(定义包装 [func] (fn [参数] (func (do-something-to params))))

而我想做的是跟踪参数变化,因为它从一个包装到另一个包装

例如,我可以定义两个包装器:

(defn wrap-inc [func] (comp func inc)) (defn wrap-double [func] (comp func #(* % 2)))

那么,

(def h (-> #(* % 3) 包装公司 包裹双))

相当于:

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

现在,我想定义 dbg-> 以便

(def h-dbg (dbg-> #(* % 3) 包装公司 包裹双))

仍然给我相同的功能等效项,但也要跟踪旧值和新值:

(h-dbg 1) => 9

但也会在控制台中显示调试信息:

“双包装:(输入:1,输出:2)” “包装公司:(输入:2,输出 3)”

这种模式对于调试像这样的环形包装器非常有用,以弄清楚每个人在做什么,例如,这个典型的例子:

(定义开始 [] (码头/运行码头 (-> #'路由处理程序 ;;(包装重新加载修改 ["clj-src"]) (包装文件“资源/公共”) 包装文件信息 换行十进制大小写参数 换行关键字参数 包装嵌套参数 包装参数 wrap-ignore-trailing-slash) {:port 8890 :join?错误的}))

【问题讨论】:

    标签: debugging clojure


    【解决方案1】:

    我相信您正在寻找一种叫做 writer monad 的东西。

    Here's 很好地解释了 Writer monad 以及它的一些实际操作示例(抱歉,它在 Haskell 中)。

    基本上,这个 monad 可以帮助您组合函数,这些函数除了“正常”输出之外还返回一个日志记录值。例如,如果你有这些类型的函数:

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

    您可以使用 writer monad 组合它们以获得具有类型的新函数:

    h :: a -> (c, l)
    

    警告:组合一元函数时,Clojure 宏 ->->> 不能以完全相同的方式使用,因为您需要使用 bind 进行组合。

    作为替代解决方案,您可以使用具有副作用的包装器:

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

    之所以有效,是因为函数体中最后一个表达式的值是它的返回值——之前的表达式被求值并且它们的结果被丢弃。

    【讨论】:

    • 我知道这和单子有关!
    【解决方案2】:

    一种快速而肮脏的方法是将其填充到宏中...此实现仅执行具有单值参数的函数。

    (定义换行打印 [f] (fn [& 参数] (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) (让 [wfncs (map #(list (list wrap-print %)) funcs)] `(-> ~n ~@wfncs ))) (dbg-> 3 inc dec) ;; =>“3 -> inc (3) -> dec (4)”

    【讨论】:

      【解决方案3】:

      也许add-watch 可以帮助您做到这一点。

      限制是您只能观看引用(atom/ref/var/agent)。

      【讨论】:

        猜你喜欢
        • 2016-09-02
        • 1970-01-01
        • 1970-01-01
        • 2018-03-07
        • 2015-02-24
        • 2011-04-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多