clojure中的记录文件
我以前有一个api,其中包含许多函数,所有这些函数都需要一个非常特殊格式的映射。当谈到记录这个API时,我发现在每个函数的docstring中我都在重复“调用这个函数的映射必须是这样那样的格式,映射的这个字段表示这样那样的” 因此,我认为这些函数最好记录一条记录,而我可以只记录该记录。然而,似乎不可能记录记录,至少不能通过clojure中的记录文件,clojure,documentation,record,Clojure,Documentation,Record,我以前有一个api,其中包含许多函数,所有这些函数都需要一个非常特殊格式的映射。当谈到记录这个API时,我发现在每个函数的docstring中我都在重复“调用这个函数的映射必须是这样那样的格式,映射的这个字段表示这样那样的” 因此,我认为这些函数最好记录一条记录,而我可以只记录该记录。然而,似乎不可能记录记录,至少不能通过doc宏或边缘体以任何方式解释记录 建议的解决方案是“只需在记录的元数据中添加一个:doc键” 我尝试了(defrecord^{:doc“这里有一些文档”}MyRecord[f
doc
宏或边缘体以任何方式解释记录
建议的解决方案是“只需在记录的元数据中添加一个:doc键”
我尝试了(defrecord^{:doc“这里有一些文档”}MyRecord[field1 field2])
,但是宏扩展这表明它没有任何效果。另外,defrecord
返回一个java.lang.class
的实例,该实例未实现IMeta,因此我不确定是否可以为其提供元数据
- 记录应如何记录
- 记录在这里是合适的解决方案吗
- TL;博士:很遗憾,你不能
从:
符号和集合支持元数据
当您使用
defrecord
时,实际上是在创建一个java类。因为类既不是符号也不是Clojure记录,所以不能向它们附加文档
更详细的解释
下面的REPL会话说明了为什么无法将元数据附加到记录中
user=> (defrecord A [a b])
#<Class@61f53f0e user.A>
user=> (meta A) ;; <= A contains no metadata
nil
显然,使用meta需要一个clojure.lang.IObj
。由于java.lang.Class
是一个java陆地构造,它显然对clojure.lang.IObj
一无所知
现在让我们看一下带有meta的的源代码
user=> (source with-meta)
(def
^{:arglists '([^clojure.lang.IObj obj m])
:doc "Returns an object of the same type and value as obj, with
map m as its metadata."
:added "1.0"
:static true}
with-meta (fn ^:static with-meta [^clojure.lang.IObj x m]
(. x (withMeta m))))
正如您所看到的,这个方法期望x
有一个withMeta
对象,而记录显然没有 您不能在记录上放置docstring。但是如果你真的想,那么你可以
如果您希望阅读代码的用户了解您的意图,那么您可以在代码中添加注释
如果希望创建记录实例的用户通过工具访问docstring,则可以修改创建的构造函数元数据。e、 g:
(let [docstring "The string-representation *MUST* be ISO8601."
arglists '([string-representation millis-since-epoch])
arglists-map '([{:keys [:string-representation :millis-since-epoch]}])]
(defrecord Timestamp [string-representation millis-since-epoch])
(alter-meta! #'->Timestamp assoc :doc docstring)
(alter-meta! #'->Timestamp assoc :arglists arglists)
(alter-meta! #'map->Timestamp assoc :doc docstring)
(alter-meta! #'map->Timestamp assoc :arglists arglists-map))
对于使用草书形式的REPL的我来说,当我要求“参数信息”时,我会看到argslist弹出窗口,当我要求“快速文档”时,会看到docstring弹出窗口
或者,更好的方法可能是为您自己的构造函数提供标准的docstring。如果您进一步阅读该线程,您会发现向记录的元数据添加:doc键是行不通的。请注意,您可以向协议中添加文档字符串。但是stack overflow answer建议不要编写仅由一条记录实现的协议,这可能会发生。一种解决方案是类似于库的,允许您指定要接受的数据类型,还允许验证所提供的参数。临时解决方案是在defrecord之前添加一个以两个分号开头的注释,该注释适用于marg,但不适用于repl
(let [docstring "The string-representation *MUST* be ISO8601."
arglists '([string-representation millis-since-epoch])
arglists-map '([{:keys [:string-representation :millis-since-epoch]}])]
(defrecord Timestamp [string-representation millis-since-epoch])
(alter-meta! #'->Timestamp assoc :doc docstring)
(alter-meta! #'->Timestamp assoc :arglists arglists)
(alter-meta! #'map->Timestamp assoc :doc docstring)
(alter-meta! #'map->Timestamp assoc :arglists arglists-map))