In Practical Common Lisp, p. 25, is a SAVE-DB function for a sample CD database which writes the contents of the database to disk, so that they can be read back in again.
That is, the line
Is there a way to make this work in Common Lisp, short of manually iterating through the contents of the hash table and printing each key and value:
(defun save-db (filename)
(with-open-file (out filename
:direction :output
:if-exists :supersede)
(with-standard-io-syntax
(print *db* out))))
(defun load-db (filename)
(with-open-file (in filename)
(with-standard-io-syntax
(setf *db* (read in)))))
This works fine when *db* is implemented as a collection of p-lists, as described in PCL, but I've modified the code, and have created a database in which the records are not just p-lists, but can also be represented as structures and hash tables. The code above works not only for p-lists, but also if the database consisted of records implemented as structures; however it fails if the implementation is a hash.That is, the line
(print *db* out)
will not work for a hash table, resulting in the error:Error: Trying to print #<EQUAL Hash Table{4} 200AFF1B> unreadably with *PRINT-READABLY* set.
1 (continue) Print #<EQUAL Hash Table{4} 200AFF1B> anyway.
2 (abort) Return to level 0.
3 Return to top loop level 0.
Type :b for backtrace, :c <option number> to proceed, or :? for other options
Is there a way to make this work in Common Lisp, short of manually iterating through the contents of the hash table and printing each key and value:
(maphash #'(lambda (k v) (print (list k v))) hash-table)
I was hoping to find a solution which would not require modifying the LOAD-DB function, so that (setf *db* (read in))
would continue to work for all 3 types of data structures.