Clojure:命名空间元数据

4
我该如何获取命名空间元数据?在repl中我这样做:
=> (in-ns my.test)
#<Namespace my.test>
=> (meta *ns*)
{:a "hello"}
=> ; Return back to repl namespace:
   (in-ns 'user)
   ; Or use 'with-ns

我的命名空间定义如下:

(ns ^{:a "hello"} my.test
  ...)

任何(meta#'my.test)变体均失败,尽管它对于def-ined实体有效。我可以理解(ns ...)不定义变量,* ns *是一个特殊变量,我无法在外部引用,但我怀疑究竟发生了什么。

1个回答

3

据我所知,长期以来存在一个问题,即传递给ns表单的符号名称附加的元数据未正确附加到命名空间对象。

作为替代方案,您可以向ns传递其他参数:

(ns foo.core
  "This is foo.core's excellent docstring."
  {:interesting "piece of metadata"}
  (:require [bar.core :as bar]))

这种样式的效果符合预期。我也觉得它更加美观。

NB. 其他引入命名对象的Clojure宏通常也会以这种方式接受额外的docstring / metadata参数:

(defn foo
  "A particularly lucid docstring for foo."
  {:trivia "The first function named foo was written in ..."}
  []
  ; ...
  )

3
此外,(meta (the-ns 'foo.core))(meta *ns*) 可以用来检索提供的元数据。 - Jared314
@Jared314 哦,是的,我忽略了关于 #'my.test 的部分。谢谢! @demi #' 用于引用 Vars(它是 var 特殊形式的简写);要根据名称获取命名空间,可以使用 the-nsfind-ns - Michał Marczyk
(source the-ns):命名空间是一个独立的实体,不是变量,所以为什么 #'my.test 不起作用。但为什么 (meta 'my.test) 失败了?从源代码来看 - the-ns 只为 x 分配类型,因此在 meta 中采取适当的分支。如果没有这个,它只是一个没有元数据的符号。 - demi
但是为什么(meta ^clojure.lang.Namespace 'my.test)会失败呢?是:static属性的魔力吗? - demi
1
(1) the-ns 检查其参数是否为命名空间对象。如果是,则返回该对象;如果不是,则假定它是一个符号,并使用 find-ns 查找该名称的命名空间。在后一种情况下,如果 find-ns 无法找到适当的命名空间,则 the-ns 抛出异常。(2) (meta 'my.test) 询问与符号 'my.test(由读取器返回)附加的元数据。这里没有附加元数据,因此正确的返回值是 nil。(3) 对 Namespace 进行 'my.test 的提示毫无意义——它实际上是一个符号。(4) #'my.test(var my.test) 的简写形式。 - Michał Marczyk
Michal,感谢你的回答!谢谢! - demi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接