myselfesteem
myselfesteem

Reputation: 755

Reading hash table from file fails

I wrote a custom reader macro for printing hash tables:

#| Custom printer for hash tables |#

;; object = hash table
;; stream = output stream
(defmethod print-object ((object hash-table) stream)
  (format stream "#H(~{~{(~S . ~S)~}~^ ~})"
          (loop for key being the hash-keys of object
                  using (hash-value value)
                collect (list key value))))

(defun hash-reader (stream char n)
  (declare (ignore char n))
  (let* ((body (read stream t nil t)))
    (loop
      with hash = (make-hash-table :test #'equal)
      for (key . val) in body do
        (setf (gethash key hash) val)
      finally (return hash))))

(set-dispatch-macro-character #\# #\H #'hash-reader)

I have a program that embeds hash tables inside a tree structure and prints out the tree to a file. Later, I want to read the tree from a file, but I get the following error:

Error (SIMPLE-ERROR) during printing: #<SIMPLE-ERROR {1020C9DA73}>

To be honest, I'm not very familiar with reader macros, and I'm not entirely sure what is wrong here. I believe the error has to do with the fact that *print-circle* is set to t. It appears that the reader is able to read the hash tables, at least initially, then for some reason it can't any more.

Code to reproduce:

(defun read-from-file (fname)
  (with-open-file (s fname)
    (read s)))

(defun save-to-file(content fname)
  (with-open-file (s fname
             :direction :output
             :if-exists :supersede
             :if-does-not-exist :create)
    (format s "~S" content)))

(defun generate-list()
  (loop
    with hash
    with prev = nil
    for i from 1 to 1000
    do
       (setq hash (make-hash-table :test #'equal))
       (setf (gethash i hash) i)
       (setq prev (cons (cons hash prev) prev))
    finally
       (return prev)))

(save-to-file (generate-list) "file.txt")
(read-from-file "file.txt")

Upvotes: 1

Views: 138

Answers (0)

Related Questions