2024 Clojure状态调查!中分享您的想法。

欢迎!请参阅关于页面以获取更多关于如何使用本站的信息。

+1 评分
ClojureScript

我正在尝试将我的datascript数据库序列化为JSON以存储在文件系统中。
我的数据库中包含一些函数。由于一些无关紧要的原因,我现在需要将它们与其他会话信息一起存储在数据库中。但是,我遇到了一个异常,transit "不能写入函数"。

我看了看代码,它只是尝试处理数据结构 - 映射、向量等。但没有处理函数的处理器。所以我知道我为什么得到错误,但我的问题是为什么它没有被实现以能够序列化函数?

是纯粹的想法太新颖了吗?

谢谢

1 答案

+2 评分

在Clojure中,函数是不透明对象,你不能从对象中恢复源代码。

defn 没有将源代码添加为元数据,这是否与 clojure.repl/source 的工作方式相同?
不,defn 存储的是变量元信息中的文件和行号(而不是函数本身),而 source 使用这些信息来查找源形式,并从源文件中读取它。这假设 a) 存在一个变量,b) 定义它的源在一个可访问的文件中。在实践中,这两者可能都不成立(在这些情况下,source 将不会工作)。
这听起来我触碰到了 clojure(script) 的工作原理,这不是一件简单的事情。感谢 @alexmiller 和 @Didier A 的回复。我现在更明白了。
我明白了。尽管在理论上可能很复杂,但你可以编写修改过的 defn 和 fn,只为那些需要序列化的函数存储函数源和环境。

例如,以下尝试做的样子:

https://github.com/sorenmacbeth/serializable-fn
https://github.com/technomancy/serializable-fn

但是,可能会有一些局限性。例如,它们不会递归地序列化它们自己调用的函数和宏。所以,当你反序列化它们时,你应该确保在一个已经包含它们所需所有 require 的命名空间下进行。

另外,我不太确定你能否在 ClojureScript 中这样做。在反序列化时,你将无法执行 eval。

总的来说,你可能需要用不同方式来解决这个问题。但如果你只是为了好玩,上述方法还是很有意思的。
...