English 中文(简体)
Common Lisp中的函数持久性
原标题:
  • 时间:2008-11-15 20:52:44
  •  标签:

有没有像象一样的通用Lisp的持久性解决方案,允许函数持久性?当前,我的应用程序在数据库中存储标识符,然后在函数表中搜索它,但此方法不允许存储动态创建的函数。

最佳回答

这不是一个数据库持久化机制,但大多数的Common Lisp都有一种方法可以用来写FASL,包括函数和各种对象。例如:

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在comp.lang.lisp上给出了一个标准解决方案。基本上,您需要将源代码写入文件中,然后编译它,再加载它。

(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*))

常见感冒可能是你想要的。它包括可序列化的闭包和可序列化的续体。

函数是不透明的对象,因此您无法将它们存储在文件或类似物中。但是,您可以将列表存储在数据库中,并在检索时进行编译。

当然,这对于存储闭包是没有帮助的。这将需要存储词法环境和代码,你都没有(便携式)访问权限。从存储列表编译的代码必须完全依赖全局数据或存储在数据库中的数据。

顺便提一下,注意您可以使用funcall符号,因此您不需要为全局函数使用函数表。

您可以查看保存Lisp映像。这允许保存“足够的信息以便在以后的某个时间重新启动Lisp进程。”您可以在将函数加载到图像中后保存它们。

这可能比你所寻找的要高级一些,但这是一个(极为)简短的过程介绍:保存核心映像

要注意,存储代码可能并不好。 Zope 开发人员吃了苦头。





相关问题
热门标签