serialization - Hacer que los objetos clos se impriman en ceceo
lisp common-lisp (1)
Si desea hacer que los objetos CLOS se impriman con ceceo comunes (imprima legiblemente), ¿cómo hace esto sin usar nada más que imprimir y leer?
Hay dos partes para hacer esto, al menos en mi solución, sin embargo necesitarás esta función (gracias a los muchachos que tienen cl-prevalence para esto ( advierte 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"))
Luego, para leer necesitará ejecutar este fragmento de código, que configura 1/2 de la sintaxis que es { 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)))))
Para imprimir, use
(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)))))
Se recomienda encarecidamente *print-readably*
al usar todos estos métodos. Además, tenga en cuenta que las relaciones circulares no han sido probadas