请参与2024年Clojure状态调查!点此进入

欢迎!请查阅关于页面,了解更多相关信息。

+1
ClojureScript

我试图将datascript数据库序列化为JSON格式,以便在文件系统中存储。
数据库中的一些数据包含函数。由于一些无关紧要的原因,我需要暂时将它们与其他会话信息一起存储在数据库中。但是,我得到了一个transit "无法写入Function"的异常。

我查看了代码,它只是尝试处理数据结构——映射、向量等。但没有为函数提供处理程序。所以我知道我为什么会得到错误,但我问题的主要内容是,为什么没有实现以序列化函数的能力?

这只是因为这是一个太新的想法吗?

谢谢

1 答案

+2

在Clojure中,函数是封闭的对象,你不能从对象中恢复源代码。

defn是否还应添加源作为元数据,这是clojure.repl/source的方式吗?
不是,defn会将文件和行号存储在var元数据中(而不是函数本身),而source则是使用这个来找到源形式,并从源文件中读取。这假设了a)存在一个变量,b)它被定义的源文件是可访问的。实际上,这两个条件可能都不成立(这是source无法工作的情况)。
听起来我触发了clojure(script)的基本工作方式,并且不仅仅是实现它的问题。感谢@alexmiller和@Didier A的回复。我现在了解得更多了。
我明白了。虽然这可能非常复杂,但在理论上的确可以编写一个修改后的defn和fn,只为你想序列化的函数存储函数源和环境。

类似于这些尝试所做的事情

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

但是,这可能会有些问题。例如,它们不会递归地序列化它们自己调用的函数和宏。所以当你反序列化它们时,你应该确保在一个已经将它们所需的所有内容导入的命名空间下进行。

此外,我不太确定你能否在ClojureScript中这样做。反序列化时你不能用eval。

总而言之,你可能想要以不同的方式处理这个问题。但如果这只是为了乐趣,上面的方法还是很让人开心的。
...