Нет необходимости в макросе:
(defn trace-ns
"ns should be a namespace object or a symbol."
[ns]
(doseq [s (keys (ns-interns ns))
:let [v (ns-resolve ns s)]
:when (and (ifn? @v) (-> v meta :macro not))]
(intern ns
(with-meta s {:traced true :untraced @v})
(let [f @v] (fn [& args]
(clojure.contrib.trace/trace (str "entering: " s))
(apply f args))))))
(defn untrace-ns [ns]
(doseq [s (keys (ns-interns ns))
:let [v (ns-resolve ns s)]
:when (:traced (meta v))]
(alter-meta! (intern ns s (:untraced (meta v)))
#(dissoc % :traced :untraced))))
... или что-то подобное. Наиболее вероятным дополнительным требованием будет использование filter
, чтобы не вызывать trace
для вещей, которые не ifn?
s Обновление: отредактировано в решении этой проблемы (также с обработкой макросов). Обновление 2: исправлены некоторые серьезные ошибки. Обновление 4: добавлена функция отслеживания.
Обновление 3: Вот пример из моего REPL:
user> (ns foo)
nil
foo> (defn foo [x] x)
#'foo/foo
foo> (defmacro bar [x] x)
#'foo/bar
foo> (ns user)
nil
user> (trace-ns 'foo)
nil
user> (foo/foo :foo)
TRACE: "entering: foo"
:foo
user> (foo/bar :foo)
:foo
user> (untrace-ns 'foo)
nil
user> (foo/foo :foo)
:foo