[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Saving CLOS objects to disk (?)



In article <spon-200793130614@spon.socs.uts.edu.au>, spon@socs.uts.oz.au
(Tom McDermott) wrote:

> Hi,
> 	is it possible to save CLOS objects to disk under MCL 2.0?  I'm trying to
> avoid having to repeatedly read-and-parse files by saving the information
> in a "predigested" form - CLOS objects.

Here's a small chunk of code I wrote to save CLOS objects to disk in a FASL
file using the hash-dot reader macro.  It's not as powerful as WOOD, but
its a bit smaller.  You need to define the method MAKE-LOAD-FORM for all
the classes you want to save.  See the examples below for more details.



;;;-----------------------------------------------------------------------------
;;; 
;;; My save object code 
;;; 
;;; Written by Kemi Jona, jona@ils.nwu.edu, 9/92
;;; 
;;;-----------------------------------------------------------------------------


(defvar *db-output* nil
  "Variable used in SAVE-OBJECT")

(defvar *db-input* nil
  "Variable used in SAVE-OBJECT")

(defun save-object (object filename &key (package *package*))
  "(object filename &key (package *package*))

Saves OBJECT to a compiled file named FILENAME. All objects referenced
must have a MAKE-LOAD-FORM method defined. Use the function 
LOAD-OBJECT to restore the object."
  
  (declare (special *db-output*))
  (let* ((full-filename (translate-logical-pathname filename))
         (tempfile (merge-pathnames "tempfile" (directory-namestring
full-filename)))
         (*.fasl-pathname* ""))
    (unwind-protect 
      (let ((*package* (find-package package)))
        (setq *db-output* object)
        (with-open-file (outstream tempfile :direction :output
                                   :if-exists :overwrite
                                   :if-does-not-exist :create)
          (format outstream "(in-package ~S)~%" (package-name
                                                 (find-package package)))
          (format outstream "(setq *db-input* '#.*db-output*)~%"))
        (compile-file tempfile :output-file filename))
      (setq *db-output* nil)
      (delete-file tempfile))
    (probe-file full-filename)))

;;; returns the object saved in filename
(defun load-object (filename)
  "(filename)

Returns the object saved to FILENAME by a call to SAVE-OBJECT."
  (declare (special *db-input*))
  (if (probe-file filename)
    (unwind-protect 
      (progn 
        (load filename) 
        *db-input*)
      (setq *db-input* nil))
    (error "File not found: ~S~%" filename)))

#|  try this as a standard make-load-form template.  see CLtL p659 for
more info.

(defmethod make-load-form ((obj your-object-class))
   (make-load-form-saving-slots obj))

Example 1: Saving lists

(let ((foo '(a b c d e)))
  (declare (ignore-if-unused foo))
  (save-object foo "save foo"))

(print (load-object "save foo"))

(delete-file "save foo")

Example 2: Saving CLOS objects 

(defclass test-class () 
  ((slot1 :initform 'hello)
   (slot2 :initform 'goodbye)))

(defmethod make-load-form ((obj test-class))
   (make-load-form-saving-slots obj))

(setq test (make-instance 'test-class))

(save-object test "save test")

(setq restored-test (load-object "save test"))

(format t "~&Original test~%")
(describe test)
(format t "~2%Restored test~%")
(describe restored-test)

(eq test restored-test)

(delete-file "save test")

|#


--Kemi

------------------------------------------------------------
Kemi Jona           jona@ils.nwu.edu             
Institute for the Learning Sciences, Northwestern University             
1890 Maple Ave., Rm. 328, Evanston, IL 60201                  
(708) 467-1969 or 491-3500     FAX: (708) 491-5258