* kp gores
| how do i "print" a hash-table to a file?
sometimes, it works to print the hash-table object with *PRINT-READABLY*
true. when that fails, you need to make a load-form for the object, and
you might legitimately expect a system to contain something to help you
with that. I found a function EXCL::MAKE-HASH-TABLE-LOAD-FORM in Allegro
CL (for Unix) which appears to offer a reasonable efficiency gain:
CL-USER(37): (let ((table (make-hash-table :test #'equal)))
(setf (gethash "foo" table) "bar")
(setf (gethash "bar" table) "zot")
(excl::make-hash-table-load-form table nil))
(let ((hash-table
(make-hash-table
:test 'equal
:size 103
:rehash-size 1.2
:rehash-threshold 0.6407767)))
(excl::hash-table-fill hash-table #("bar" "zot" "foo" "bar")))
it appears that the other way to handle this, using the FASL read/write
functions in Allegro CL (for Unix), actually produces the exact same
function calls on loading as the above load-form. this probably
shouldn't come as a surprise, but, anyway, here's how to write and read a
hash table to a file with the simplest FASL read/write mechanism:
CL-USER(47): (let ((table (make-hash-table :test #'equal)))
(setf (gethash "foo" table) "bar")
(setf (gethash "bar" table) "zot")
(fasl-write table "/tmp/hash-table.fasl"))
t
CL-USER(48): (fasl-read "/tmp/hash-table.fasl")
(#<equal hash-table with 2 entries @ #x2076ae82>)
if you wish to write more objects to the same file, use FASL-OPEN to get
a FASL stream and write to it, instead:
CL-USER(53): (with-open-stream (fasl (fasl-open "/tmp/hash-table.fasl"))
(let ((table (make-hash-table :test #'equal)))
(setf (gethash "foo" table) "bar")
(setf (gethash "bar" table) "zot")
(fasl-write table fasl)
(fasl-write table fasl)))
t
CL-USER(54): (fasl-read "/tmp/hash-table.fasl")
(#<equal hash-table with 2 entries @ #x20799e2a>
#<equal hash-table with 2 entries @ #x2079a4d2>)
| i want to read the hash-table back from a file later, work with it,
| add/delete entries and then save it back.
this sounds more like you actually want a "hash table" to reside on disk
and have a mapping onto a simple file-based database. or in other words,
persistent objects.
neither printable/loadable hash tables nor persistent objects are fully
portable features in Common Lisp, i.e., you will need to use functions
specific to the implementation in _some_ way. other Common Lisps offer
other ways than Allegro CL, but the above is at least how I do it.
#:Erik
--
http://www.naggum.no/spam.html is about my spam protection scheme and how
to guarantee that you reach me. in brief: if you reply to a news article
of mine, be sure to include an In-Reply-To or References header with the
message-ID of that message in it. otherwise, you need to read that page.