假设如下,
(in-ns silly.fun)
(def a 1)
(defn fx [b]
((fn [c] (return-all-symbols)) (first b)))
我想知道是否可以有一个 return-all-symbols 函数来返回当前在其调用范围内的符号/值的映射。因此,假设上面的代码已编译并且我们位于 'silly.fun 命名空间中,我们可以运行如下所示的代码。
(fx [:hello]) => {"a" 1, "b" [:hello], "c" :hello}
我想使用 return-all-symbols 进行调试。返回所有符号是否可能?如果是这样,它的实现是什么?
最佳答案
这是可能的,但正如您所定义的那样,您会非常难过:您不想要一个包含数百个条目的映射,这些条目引用了 clojure.core 中的所有函数!即使您只查看当前 namespace ,您也会忘记包含 fx
,它是一个值为函数的符号。另外,通常还会有您不想要的由宏引入的词汇符号。例如,(let [[x y] foo])
将显示四个可用符号:foo、x、y 以及诸如 vec__auto__4863
之类的符号。
无论如何,您可能必须在这些问题上做出一些妥协,否则(我真的认为这更好)指定您实际上想要哪些符号的 map 。但是要自动获取那些 (a) 词法或 (b) 在当前命名空间中定义的符号的值,并且 (c) 不映射到函数,您可以使用:
(defmacro return-all-symbols []
(let [globals (remove (comp :macro meta val) (ns-publics *ns*))
syms (mapcat keys [globals, &env])
entries (for [sym syms]
[`(quote ~sym) sym])]
`(into {}
(for [[sym# value#] [~@entries]
:when (not (fn? value#))]
[sym# value#]))))
(def a 1)
(defn fx [b]
((fn [c] (return-all-symbols)) (first b)))
(fx [:hello])
;=> {a 1, c :hello, b [:hello]}
关于debugging - 返回 Clojure 中当前所有作用域符号的表达式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12502933/