我的日志记录(使用robert-hooke)无法正常使用tools.namespace / refresh,为什么?

时间:2014-02-11 22:42:23

标签: clojure namespaces

编辑:原来我在名称空间声明中使用require而不是:require。使用:require,tools.namespace会刷新日志记录命名空间,问题就会消失。然而,我仍然感到奇怪的是,表达式(eval `(var ~(symbol "A/func")))在下面描述的情况下不起作用(即,如果下面的B不刷新)。

总结:我正在使用tools.namespace。如果我有名称空间A和B,并且在B中执行(eval `(var ~(symbol "A/func")))(tools.namespace/refresh)并运行代码,则可行。但是,如果我对A进行了更改,请执行(tools.namespace/refresh),以便只刷新A,然后运行该表达式会出现错误:Cannot resolve var: A/func in this context,即使存在A/func。为什么呢?

更长的版本:

在我的项目中,我有一个使用robert-hooke的日志模块/命名空间(见下文)。我在进行更改时使用tools.namespace重新加载代码。

问题如下:当我想记录(我的日志记录当前只是打印)时,我列出了我想要记录在日志命名空间中的函数并执行(t.n/refresh)。这样可行。但是,如果我对包含我要记录的函数的命名空间进行更改,并且在不更改日志记录命名空间的情况下执行(t.n/refresh),则日志记录将不再起作用(对于已刷新的函数)。一旦我对日志记录进行了更改,以便tools.namespace刷新它,它就会重新开始工作。

因此,它就像已刷新的名称空间中的变量无法正确获取其日志记录挂钩。但我不明白为什么。

下面是我的日志命名空间。我每次运行程序时都会调用add-logging-wrappers

如果我在(eval `(var ~(symbol "sv/register-damage")))内添加add-logging-wrappers,那么在刚刚刷新日志记录并且日志记录正常工作时就可以了。但是那些日志记录不起作用的时候,该表达式会导致错误Cannot resolve var: sv/register-damage in this context

(ns game.logging
  (require [robert.hooke :as rh]
           [clojure.pprint :as pp]
           [game.server.core :as sv]
           [game.client.core :as cl]
           [game.math :as math]
           (game.common [core-functions :as ccfns]
                        [graphics :as gfx])
           (game.server [pathfinding :as pf]))
  (:use [game.utils]))

(defn log-println [name type object]
  (println (str (current-thread-name) " // " name " " type ":\n"
                (with-out-str
                  (pp/pprint object)))))

(defn print-output [name f & args]
  (let [result (apply f args)]
    (log-println name "output" result)
    result))

(defn print-input [name f & args]
  (log-println name "input" args)
  (apply f args))

(defn print-call [name f & args]
  (println (str (current-thread-name) "//" name))
  (apply f args))

(defmacro make-name-var-list [fn-list]
  `[~@(for [fn fn-list]
        [(str fn) `(var ~fn)])])

(defmacro defloglist [name & fns]
  `(def ~name (make-name-var-list [~@fns])))

(defn add-hooks [name-vars & wrappers]
  (when (seq wrappers)
    (doseq [[name var] name-vars]
      (rh/add-hook var (partial (first wrappers) name)))
    (recur name-vars (next wrappers))))

(defn get-ns-name-vars [ns-sym]
  (-> (the-ns ns-sym) (#(.name %)) ns-interns))

(defn add-hooks-to-ns [ns-sym & wrappers]
  (apply add-hooks (get-ns-name-vars ns-sym) wrappers))

(defloglist log-both 
  sv/distribute-exp     ;; <--- things to log
  sv/register-damage
  sv/give-exp)

(defloglist log-input)

(defloglist log-output)

(defn add-logging-wrappers []
  (dorun (->> (all-ns) (map #(.name %)) (mapcat ns-interns) (map second)
              (map rh/clear-hooks)))
  (add-hooks log-both print-output print-input)
  (add-hooks log-input print-input)
  (add-hooks log-output print-output))

0 个答案:

没有答案