【问题标题】:Make clos objects printable in lisp使 clos 对象在 lisp 中可打印
【发布时间】:2011-03-06 10:04:29
【问题描述】:

如果你想让普通 lisp 中的 CLOS 对象可打印(打印可读),你如何在不使用任何东西但打印和读取的情况下做到这一点。

【问题讨论】:

    标签: serialization lisp common-lisp clos


    【解决方案1】:

    这样做有两个部分,至少在我的解决方案中,但是你将需要这个函数(感谢 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"))
    

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

    (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)))))
    

    对于打印,使用

    (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)))))
    

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

    【讨论】:

    • 你应该有一个平衡的外部表示。目前您有一个开始字符,但没有相应的结束字符。对于阅读,请参见例如 READ-DELIMITED-LIST。请参阅lispworks.com/documentation/lw50/CLHS/Body/f_rd_del.htm 的示例。
    • 也许你是对的,但它很适合我的目的,因为在 { 之后必须 恰好两个对象
    • 是的,但它会让所有编辑感到困惑。 s-表达式应该是平衡的。无论如何,这是一个简单的改变。
    • 是的,但是您在 Stackoverflow 上发布了一个丑陋的 hack,其他人可能会复制它。如果您只将其保留在您的软件中,那么处理它只是您的问题。在 Stackoverflow 上发布不合标准的代码不是一个好主意。您的代码根本不是一个很好的例子。基于 S-Expression 的格式是平衡的,Common Lisp 已经给出了结构外部格式的示例。
    • 使用更紧密的拖把效果更好
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-04-26
    • 1970-01-01
    • 1970-01-01
    • 2012-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多