2008-11-15 18 views
9

¿Existe alguna solución de persistencia para Common Lisp, como Elephant, que permita la persistencia de la función? Actualmente, mi aplicación almacena un identificador en el archivo db y luego busca en una tabla de funciones, pero este método no permite almacenar funciones creadas dinámicamente.Función de persistencia en Common Lisp

Respuesta

4

No es un mecanismo de persistencia de base de datos, pero la mayoría de Lisps comunes tienen una forma de writing FASLs para todo tipo de objetos, incluidas las funciones. Por ejemplo:

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

puede escribir a una corriente (en este caso he utilizado un archivo por conveniencia), por lo que puede trivialmente capturar esos bytes y meterlas en una base de datos si hubiese deseado.

+1

Pero debe tener en cuenta que no está en el estándar CL. –

1

Las funciones son objetos opacos, por lo que no tendrás mucha suerte en almacenarlos en archivos o algo así. Sin embargo, puede almacenar listas y compile al recuperarlas de la base de datos.

Esto no le ayudará a almacenar cierres, por supuesto. Eso implicaría almacenar el entorno léxico junto con el código, ninguno de los cuales tiene acceso (portátil). El código que compila a partir de listas almacenadas deberá depender totalmente de los datos o datos globales almacenados en la base de datos.

Por cierto, tenga en cuenta que puede funcall símbolos, por lo que no necesita una tabla de funciones para funciones globales.

1

Puede buscar guardar imágenes Lisp. Esto permite guardar "información suficiente para reiniciar un proceso Lisp en un momento posterior". Puede guardar sus funciones después de haberlas cargado en su imagen.

Esto también puede ser un poco más avanzado que lo que estaba buscando, pero aquí es una (muy) breve introducción al proceso: Saving a Core Image

2

Common Cold podría ser lo que quieras. Incluye cierres serializables y continuaciones serializables.

3

Pascal Bourguignon dio un standard solution on comp.lang.lisp. Básicamente, debe escribir el formulario fuente en un archivo y COMPILE y luego 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))) 

Luego tendrá que leer el archivo y guardarlo en su base de datos. Para recuperarlo, deberá recuperarlo de la base de datos y escribirlo en un archivo antes de cargarlo.

(defun load-anonymous-function (fname) 
    (let ((*load-verbose* nil) 
     (*anon* nil)) ; to avoid modifying the global one. 
    (load fname) 
    *anon*)) 
0

Tenga cuidado de que el código de almacenamiento no sea tan bueno. Los desarrolladores de Zope lo aprendieron de la manera difícil.

+1

¿Qué se supone que significa eso? Un poco más explícito sería mucho más útil ... – AticusFinch