如何将 clojure 的 doc 函数应用于一系列函数

发布于 2024-12-19 05:28:46 字数 522 浏览 2 评论 0原文

我试图做一些我认为很简单的事情,但事实证明并非如此,我认为该解决方案可能会让我对 clojure 有更深入的了解,所以我想我会在这里问。

我希望能够从 clojure REPL 运行以下命令:

(map #(doc %) v)

其中 v 是...某物的向量,我不确定是什么。目标是打印出某些函数序列的文档字符串,但我不确定如何表达该向量。我尝试了几件事:(我会随机挑选一些功能)

[+ - first set]
['+ '- 'first 'set]
[`+ `- `first `set]
[(var +) (var -) (var first) (var set)]
[`~+ `~- `~first `~set]

没有任何作用。我还尝试应用 doc 函数,但这不起作用,因为 doc 是一个宏,因此不能作为 的参数>应用。我缺少什么?

I was trying to do something I thought would be simple but has turned out to be not so and I think the solution might give me a deeper understanding of clojure so I figured I'd ask here.

I want to be able to run the following from a clojure REPL:

(map #(doc %) v)

where v is a vector of...something, I'm not sure what. The goal was to print out the doc strings for some sequence of functions, but I'm not sure how to express that vector. I've tried a couple of things: (I'll pick a few functions out at random)

[+ - first set]
['+ '- 'first 'set]
[`+ `- `first `set]
[(var +) (var -) (var first) (var set)]
[`~+ `~- `~first `~set]

None work. I also tried to apply the doc function but that doesn't work since doc is a macro and as such cannot be an argument to apply. What am I missing?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

葬シ愛 2024-12-26 05:28:46
(doseq [f ['+ '- 'first 'set]] (eval (list 'doc f)))
(doseq [f ['+ '- 'first 'set]] (eval (list 'doc f)))
月竹挽风 2024-12-26 05:28:46

在 Clojure 1.2 中,您可以使用函数 print-doc

(print-doc #'fisrt)

这样

(map print-doc [#'fisrt #'+])

#'fisrt(var first) 相同。

请注意,这不适用于特殊形式: (doc def) 有效,但 (print-doc #def)` 给出:

java.lang.Exception: Unable to resolve var: def in this context (NO_SOURCE_FILE:7)

这是因为未定义特殊形式在变量中。您可以使用 macroexpand-1 了解 doc 如何为它们工作:

user=> (macroexpand-1 '(doc def))
(clojure.core/print-special-doc (quote def) "Special Form" (clojure.core/special-form-anchor (quote def)))

在 Clojure 1.3 中,print-doc 被移动到 clojure.repl 命名空间中,并且是私有的,所以你不能直接执行它。您可以输入 ns:

user=> (in-ns 'clojure.repl)
clojure.repl=> (print-doc (meta #'first))
clojure.repl=> (map #(print-doc (meta %)) [#'first #'+])

如您所见,Clojure 1.3 需要显式获取元数据。

如果您需要从不同的命名空间执行此操作,则必须导出该函数。一种方法是定义一个新函数:

clojure.repl=> (defn my-print-doc [m] (print-doc m))
user=> (clojure.repl/my-print-doc (meta #'first))

In Clojure 1.2 you can use the function print-doc:

(print-doc #'fisrt)

like this

(map print-doc [#'fisrt #'+])

#'fisrt is the same as (var first).

Note that this will not work for special forms: (doc def) works, but (print-doc #def)` gives:

java.lang.Exception: Unable to resolve var: def in this context (NO_SOURCE_FILE:7)

This is because special forms aren't defined in vars. You can see how doc works for them by using macroexpand-1:

user=> (macroexpand-1 '(doc def))
(clojure.core/print-special-doc (quote def) "Special Form" (clojure.core/special-form-anchor (quote def)))

In Clojure 1.3 print-doc is moved in the clojure.repl namespace and is private, so you cannot execute it directly. You can enter the ns:

user=> (in-ns 'clojure.repl)
clojure.repl=> (print-doc (meta #'first))
clojure.repl=> (map #(print-doc (meta %)) [#'first #'+])

As you can see, Clojure 1.3 requires getting the metadata explicitly.

If you need to execute this from a different namespace you'll have to export the function. One way to do so is to define a new function:

clojure.repl=> (defn my-print-doc [m] (print-doc m))
user=> (clojure.repl/my-print-doc (meta #'first))
故事未完 2024-12-26 05:28:46
(defn my-doc [v] (-> v meta :doc))

该函数获取 var 的元数据,然后从元数据中获取文档字符串。
您可以将其映射到一系列变量上:

(map my-doc [(var +) (var -) (var first) (var set)]) ;=> LazySeq of doc-strings

或更短:

(map my-doc [#'+ #'- #'first #'set]) ;=> LazySeq of doc-strings

这不适用于特殊形式,因为它们不被变量引用。

(defn my-doc [v] (-> v meta :doc))

This function takes the meta data of a var and then gets the doc string out of the meta data.
You can map it over a sequence of vars:

(map my-doc [(var +) (var -) (var first) (var set)]) ;=> LazySeq of doc-strings

or shorter:

(map my-doc [#'+ #'- #'first #'set]) ;=> LazySeq of doc-strings

This doesn't work for special forms, since they are not referenced by vars.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文