我总是希望有一种方法可以自动解析符号。例如,如果我在“user”命名空间中并且在`clojure.string'命名空间中没有“使用”符号,而不是:
(clojure.string/split "a-b-c" #"-")
我想这样写:
(call split "a-b-c" #"-")
我只是实现了一个`call'宏:
(defmacro call [sym & args]
`(let [fn# (first (distinct (remove nil? (map #(ns-resolve % '~sym) (all-ns)))))]
(if-not ((meta fn#) :macro)
(fn# ~@args)
(eval (list fn# ~@(map #(list 'quote %) args))))))
以下测试总是可以的:
(call list 'a 'b)
(call apropos "list")
(call doc list)
(call doc clojure.string/split)
当我将宏作为`doc'的参数传递时,问题就出现了:
(call doc clojure.repl/doc)
然后,有一个例外:
CompilerException java.lang.RuntimeException:无法获取宏的值:#'clojure.repl / doc,编译:(NO_SOURCE_PATH:112)
那么,那是为什么?感谢
答案 0 :(得分:2)
您可以在宏中编译时解析符号,如下所示:
(defmacro call [sym & args]
(let [f (first (distinct (remove nil? (map #(ns-resolve % sym) (all-ns)))))]
`(~f ~@args)))