我发现对于任何在 clojure.tools.macro 中编写类似 defn
的宏的人来说,这将是一个很棒的工具。图书馆:name-with-attributes
功能。文档字符串说:
To be used in macro definitions. Handles optional docstrings and attribute maps for a name to be defined in a list of macro arguments. If the first macro argument is a string, it is added as a docstring to name and removed from the macro argument list. If afterwards the first macro argument is a map, its entries are added to the name's metadata map and the map is removed from the macro argument list. The return value is a vector containing the name with its extended metadata map and the list of unprocessed macro arguments.
但我似乎找不到在任何地方使用此函数的示例。
那么,我如何使用这个函数来定义一个 defn2
宏,它应该是包含所有相同内容的 clojure.core/defn
的克隆功能,包括:
- 文档字符串
- 属性映射
- 先决条件
- 多方面
最佳答案
这是defn2
:
(require '[clojure.tools.macro :as ctm])
(defmacro defn2
"A clone of `defn`."
[symb & defn-args]
(let [[symb body] (ctm/name-with-attributes symb defn-args)]
`(defn ~symb ~@body)))
查看元数据,我们可以看到它已正确附加:
(defn2 ^:private add
"Docstring"
([] :foo)
([a b] {:pre [(= 1 1)]} (+ a b)))
(pprint (meta #'add))
...产量:
{:arglists ([] [a b]),
:ns #<Namespace user>,
:name add,
:column 1,
:private true,
:doc "Docstring",
:line 1,
:file
"/private/var/folders/30/v73zyld1359d7jb2xtlc_kjm0000gn/T/form-init8938188655190399857.clj"}
使用上面的 defn2
创建了一个 add
函数,其工作方式如下:
(add) ; => :foo
(add 1 2) ; => 3
关于macros - 如何使用 `clojure.tools.macro/name-with-attributes` ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25478158/