Guest User

Untitled

a guest
Aug 20th, 2020
100
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lisp 3.63 KB | None | 0 0
  1. ;;; Metaobject Protocol
  2.  
  3. (require 'closer-mop)
  4. (require 'alexandria)
  5.  
  6. (defclass attributes-class (standard-class) ())
  7.  
  8. ;; The following is from
  9. ;; https://stackoverflow.com/questions/21986977/additional-properties-to-slot-definition
  10. ;; (I was getting the same error)
  11. ;; I added the accessors, too.
  12.  
  13. (defclass attributes-direct-slot-definition (c2mop:standard-direct-slot-definition)
  14.   ((attributes :initform nil :initarg :attributes :accessor attributes)))
  15.  
  16. (defclass attributes-effective-slot-definition (c2mop:standard-effective-slot-definition)
  17.   ((attributes :initform nil :initarg :attributes :accessor attributes)))
  18.  
  19. (defmethod c2mop:direct-slot-definition-class ((class attributes-class) &rest initargs)
  20.   (find-class 'attributes-direct-slot-definition))
  21.  
  22. (defmethod c2mop:effective-slot-definition-class ((class attributes-class) &rest initargs)
  23.   (find-class 'attributes-effective-slot-definition))
  24.  
  25. (defmethod c2mop:validate-superclass ((class attributes-class)
  26.                                       (superclass standard-class))
  27.   t)
  28.  
  29. ;; The rest is from the Art of the Metaobject Protocol p. 87
  30.  
  31. (defmethod c2mop:compute-effective-slot-definition ((class attributes-class)
  32.                                                     name ;; the book doesn't have this parameter
  33.                                                     direct-slots)
  34.   (let ((normal-slot (call-next-method)))
  35.     (setf (attributes normal-slot)
  36.           (remove-duplicates
  37.            (alexandria:mappend #'attributes direct-slots)))
  38.     normal-slot))
  39.  
  40. (defmethod c2mop:compute-slots ((class attributes-class))
  41.   (let* ((normal-slots (call-next-method))
  42.          (alist (mapcar (lambda (slot)
  43.                           (cons (c2mop:slot-definition-name slot)
  44.                                 (mapcar (lambda (attr) (cons attr nil))
  45.                                         (attributes slot))))
  46.                         normal-slots)))
  47.     (cons (make-instance 'c2mop:effective-slot-definition
  48.                          :name 'all-attributes
  49.                          :initform `',alist
  50.                          :initfunction (lambda () alist))
  51.           normal-slots)))
  52.  
  53. (defun slot-attribute-bucket (instance slot-name attribute)
  54.   (let* ((all-buckets (slot-value instance 'all-attributes))
  55.          (slot-bucket (assoc slot-name all-buckets)))
  56.     (unless slot-bucket
  57.       (error "The slot named ~S of ~S has no attributes."
  58.              slot-name instance))
  59.     (let ((attr-bucket (assoc attribute (cdr slot-bucket))))
  60.       (unless attr-bucket
  61.         (error "The slot named ~S of ~S has no attribute named ~S."
  62.                slot-name instance attribute))
  63.       attr-bucket)))
  64.  
  65. (defun slot-attribute (instance slot-name attribute)
  66.   (cdr (slot-attribute-bucket instance slot-name attribute)))
  67.  
  68. (defun (setf slot-attribute) (new-value instance slot-name attribute)
  69.   (setf (cdr (slot-attribute-bucket instance slot-name attribute))
  70.         new-value))
  71.  
  72. ;; test code
  73.  
  74. (defclass credit-rating ()
  75.   ((level :attributes (date-set time-set)))
  76.   (:metaclass attributes-class))
  77.  
  78. (setq cr (make-instance 'credit-rating))
  79. ;; =>
  80. ;; There is no applicable method for the generic function
  81. ;;   #<STANDARD-GENERIC-FUNCTION SB-MOP:SLOT-DEFINITION-ALLOCATION (3)>
  82. ;; when called with arguments
  83. ;;   (#<SB-MOP:EFFECTIVE-SLOT-DEFINITION COMMON-LISP-USER::ALL-ATTRIBUTES>).
  84.  
  85. ;; == Fix attempt, copied from std-class.lisp ==
  86. (defmethod c2mop:slot-definition-allocation ((slotd attributes-effective-slot-definition))
  87.   :instance)
  88.  
  89. (slot-attribute cr 'level 'date-set)
  90. (setf (slot-attribute cr 'level 'date-set) "123/324/41")
  91. (slot-attribute cr 'level 'date-set)
  92.  
Add Comment
Please, Sign In to add comment