在Clojure中从命令行设置调试函数

在Clojure中从命令行设置调试函数,clojure,Clojure,我有这样一个名称空间: (ns foo.core) (def ^:dynamic *debug-fn* "A function taking arguments [bar baz]" nil) (defn bar-info [bar _] (println bar)) (defn baz-info [_ baz] (println baz)) (defn do-stuff [bar baz] (when *debug-fn* (*debug-fn* bar

我有这样一个名称空间:

(ns foo.core)

(def ^:dynamic *debug-fn*
  "A function taking arguments [bar baz]"
  nil)

(defn bar-info
  [bar _]
  (println bar))

(defn baz-info
  [_ baz]
  (println baz))

(defn do-stuff
  [bar baz]
  (when *debug-fn* (*debug-fn* bar baz)))

(defn -main
  [& {:keys [debug-fn]}]
  (binding [*debug-fn* (symbol debug-fn)]  ;; THIS WON'T WORK!
    (do-stuff 27 42)))
我想做的是允许从命令行指定调试函数,如下所示:
lein run bar info
lein run baz info


我不知道如何将指定为命令行参数的字符串转换为要绑定的命名空间限定函数。是否需要宏来执行此操作?

使用
alter var root

user=> (doc alter-var-root)
-------------------------
clojure.core/alter-var-root
([v f & args])
  Atomically alters the root binding of var v by applying f to its
  current value plus any args
nil
user=> (alter-var-root #'*debug-fn* (fn [v] (fn [x] (println x) x)))
#<user$eval171$fn__172$fn__173 user$eval171$fn__172$fn__173@7c93d88e>
user=> (*debug-fn* 1)
1
1
user=>(doc alter var root)
-------------------------
clojure.core/alter-var-root
([v f&args])
通过将f应用于var v的根绑定,原子地改变var v的根绑定
当前值加上任何参数
无
user=>(alter var root#'*debug fn*(fn[v](fn[x](println x)x)))
#
用户=>(*debug fn*1)
1.
1.
使用时,您需要指定定义函数的名称空间

user=> (defn f [n] (* n n n))
#'user/f
user=> ((ns-resolve *ns* (symbol "f")) 10)
1000
虽然我已经接受了,但我认为添加我最终使用的解决方案也可能有用:

(def debug-fns
  {:bar-info (fn [bar _] (println bar))
   :baz-info (fn [_ baz] (println baz))

(def active-debug-fns (atom []))

(defn activate-debug-fn!
  [fn-key]
  (let [f (debug-fns fn-key)]
    (if f
      (swap! active-debug-fns conj f)
      (warn (str "Debug function " fn-key " not found! Available functions are: "
                 (join " " (map name (keys debug-fns))))))))

(defn debug-fn-keys
  [args]
  (if (args "--debug")
    (split (or (args "--debug") "") #",")
    []))

(defn do-stuff
  [bar baz]
  (doseq [f @active-debug-fns]
    (f bar baz)))

(defn -main
  [& args]
  (let [args (apply hash-map args)]
    (doseq [f (debug-fn-keys args)]
      (activate-debug-fn! (keyword k)))
    (do-stuff 27 42)))
现在你可以说
lein-run--debug bar info
来获取关于条的信息,或者
lein-run--debug bar,baz
来获取关于条和条的信息


任何让这篇文章更地道的建议都将被愉快地接受并在中编辑。:)

我认为问题不在于绑定,而在于从字符串到可调用函数的转换。是的,我现在明白了。抱歉:)嗯,绑定也有问题,因为我真正的
do stuff
函数创建了一个带有一些回调的Swing面板,从而破坏了我使用
绑定的良好意图。所以谢谢你!