Common Lisp是否存在允许函数持久性的持久性解决方案?目前我的应用程序在数据库上存储了一个标识符,后来在函数表中进行了搜索,但是这种方法不允许存储动态创建的函数。
答案 0 :(得分:4)
它不是数据库持久性机制,但是大多数Common Lisp对于所有类型的对象(包括函数)都有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>)
你可以写一个流(这里为了方便我使用了一个文件),所以如果你愿意的话,你可以平凡地捕获这些字节并将它们填充到数据库中。
答案 1 :(得分:3)
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*))
答案 2 :(得分:2)
Common Cold可能就是你想要的。它包括可序列化的闭包和可序列化的延续。
答案 3 :(得分:1)
函数是不透明的对象,因此您不会将它们存储在文件或类似的东西中。但是,您可以在从数据库中检索时存储列表和compile。
当然,这不会帮助您存储闭包。这将需要存储词汇环境以及代码,这些代码都没有(便携式)访问权限。从存储列表编译的代码必须完全依赖于存储在数据库中的全局数据或数据。
顺便说一句,请注意您可以使用funcall符号,因此您不需要全局函数的函数表。
答案 4 :(得分:1)
您可以查看保存Lisp图像。这样可以保存“足够的信息,以便以后重新启动Lisp进程”。将功能加载到图像后,可以保存功能。
这也可能比你想要的更先进一些,但这里有一个(非常)简要介绍过程:Saving a Core Image
答案 5 :(得分:0)
小心存储代码可能不那么好。 Zope的开发人员很难学到它。