请在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)操作。

总的来说,你可能希望以不同的方式来解决这个问题。但如果这只是为了娱乐,上述方法还是挺有趣的。
...