【发布时间】:2008-11-15 20:52:44
【问题描述】:
是否有任何针对 Common Lisp 的持久化解决方案,例如 Elephant,它允许函数持久化?目前我的应用程序在数据库上存储一个标识符,然后在一个函数表中搜索它,但这种方法不允许存储动态创建的函数。
【问题讨论】:
标签: database lisp persistence common-lisp
是否有任何针对 Common Lisp 的持久化解决方案,例如 Elephant,它允许函数持久化?目前我的应用程序在数据库上存储一个标识符,然后在一个函数表中搜索它,但这种方法不允许存储动态创建的函数。
【问题讨论】:
标签: database lisp persistence common-lisp
它不是一种数据库持久化机制,但大多数 Common Lisps 对各种对象(包括函数)都有writing FASLs 的方式。例如:
cl-user(1): (compile (defun hello () (format t "~&Hello~%")))
hello
nil
nil
cl-user(2): (excl:fasl-write (symbol-function 'hello) "/tmp/hello.fasl")
t
cl-user(3): (excl:fasl-read "/tmp/hello.fasl")
(#<Function hello @ #x1000a964d2>)
您可以写入流(为了方便起见,我在这里使用了文件),因此您可以轻松捕获这些字节并将它们填充到数据库中。
【讨论】:
Pascal Bourguignon 给出了standard solution on comp.lang.lisp。基本上你必须将源表单写入一个文件,然后COMPILE它然后LOAD它。
(defvar *anon*)
(defun save-anonymous-function (fname args body)
(let ((fname (make-pathname :type "LISP" :case :common :defaults fname)))
(with-open-file (src fname :direction :output
:if-does-not-exist :create :if-exists :supersede)
(print `(defparameter *anon* (lambda ,args ,body)) src))
(compile-file fname)))
然后您必须读取该文件并将其存储在您的数据库中。要取回它,您需要从数据库中获取它并在加载之前将其写入文件中。
(defun load-anonymous-function (fname)
(let ((*load-verbose* nil)
(*anon* nil)) ; to avoid modifying the global one.
(load fname)
*anon*))
【讨论】:
Common Cold 可能是您想要的。它包括可序列化的闭包和可序列化的延续。
【讨论】:
您可以考虑保存 Lisp 图像。这允许保存“足够的信息以在以后重新启动 Lisp 进程”。您可以在将函数加载到图像后保存它们。
这也可能比您所寻找的更高级,但这里是(非常)简要介绍该过程:Saving a Core Image
【讨论】:
请注意,存储代码可能不是那么好。 Zope 开发人员通过艰难的方式学会了这一点。
【讨论】: