使clos对象在lisp中可打印

krz*_*z00 11 lisp serialization common-lisp clos

如果你想使CLOS对象成为常见的lisp可打印(可读打印),那么如何在不使用打印和读取的情况下进行此操作.

krz*_*z00 5

这有两个部分,至少在我的解决方案中,但是你将需要这个功能(感谢cl-prevalence的人(警告LLGPL)

(defun get-slots (object)
  ;; thanks to cl-prevalence
  #+openmcl
  (mapcar #'ccl:slot-definition-name
      (#-openmcl-native-threads ccl:class-instance-slots
       #+openmcl-native-threads ccl:class-slots
       (class-of object)))
  #+cmu
  (mapcar #'pcl:slot-definition-name (pcl:class-slots (class-of object)))
  #+sbcl
  (mapcar #'sb-pcl:slot-definition-name (sb-pcl:class-slots (class-of object)))
  #+lispworks
  (mapcar #'hcl:slot-definition-name (hcl:class-slots (class-of object)))
  #+allegro
  (mapcar #'mop:slot-definition-name (mop:class-slots (class-of object)))
  #+sbcl
  (mapcar #'sb-mop:slot-definition-name (sb-mop:class-slots (class-of object)))
  #+clisp
  (mapcar #'clos:slot-definition-name (clos:class-slots (class-of object)))
  #-(or openmcl cmu lispworks allegro sbcl clisp)
  (error "not yet implemented"))
Run Code Online (Sandbox Code Playgroud)

然后,为了阅读,你需要运行这段代码,它设置了1/2的语法 { type-of-object ((slot-name . slot-value) (slot-name . slot-value) ...)

(set-macro-character 
     #\{
     #'(lambda (str char)
     (declare (ignore char))
     (let ((list (read-delimited-list #\} str t)))
       (let ((type (first list))
         (list (second list)))
         (let ((class (allocate-instance (find-class type))))
           (loop for i in list do
            (setf (slot-value class (car i)) (cdr i)))
           class)))))
Run Code Online (Sandbox Code Playgroud)

用于打印,使用

(defmethod print-object ((object standard-object) stream)
  (format stream "{ ~s ~s}" (type-of object)
      (loop for i in (get-slots object)
    collect (cons i (slot-value object i)))))
Run Code Online (Sandbox Code Playgroud)

*print-readably*使用所有这些方法时,强烈建议使用A. 另请注意,循环关系未经测试

  • 是的,但你在Stackoverflow上发布了一个丑陋的黑客,其他人可能会复制它.如果只保留给您的软件,处理它只是您的问题.在Stackoverflow上发布不合标准的代码不是一个好主意.你的代码不是一个好例子.基于S表达式的格式是平衡的,Common Lisp已经给出了结构的外部格式的示例. (10认同)
  • 使用close-mop要好得多 (4认同)
  • 你应该有一个平衡的外部代表.目前您有一个开头字符,但没有相应的结束字符.有关阅读,请参阅例如READ-DELIMITED-LIST.请参阅http://www.lispworks.com/documentation/lw50/CLHS/Body/f_rd_del.htm上的示例. (3认同)