common-lisp
CLOS Meta-Object Protocol
Szukaj…
Uzyskaj nazwy miejsc klasy
Powiedzmy, że mamy klasę jako
(defclass person ()
(name email age))
Aby uzyskać nazwy gniazd klasy, używamy funkcji klasy-sloty. Można to znaleźć w pakiecie bliższego mopa, dostarczanego przez system bliższego mopa. Do załadowania używamy działającego obrazu (ql:quickload :closer-mop)
. Musimy również upewnić się, że klasa jest sfinalizowana przed wywołaniem miejsc na klasy.
(let ((class (find-class 'person)))
(c2mop:ensure-finalized class)
(c2mop:class-slots class))
która zwraca listę efektywnych obiektów definicji boksu:
(#<SB-MOP:STANDARD-EFFECTIVE-SLOT-DEFINITION S/TRANSFORMATIONS::NAME>
#<SB-MOP:STANDARD-EFFECTIVE-SLOT-DEFINITION S/TRANSFORMATIONS::EMAIL>
#<SB-MOP:STANDARD-EFFECTIVE-SLOT-DEFINITION S/TRANSFORMATIONS::AGE>)
Zaktualizuj miejsce, gdy zostanie zmodyfikowane inne miejsce
MOP CLOS zapewnia przechwytującą wartość szczeliny klasy użytkowej, która jest wywoływana, gdy dostęp do szczeliny jest uzyskiwany, odczytywany lub modyfikowany. Ponieważ dbamy tylko o modyfikacje w tym przypadku, definiujemy metodę dla (setf slot-value-using-class)
.
(defclass document ()
((id :reader id :documentation "A hash computed with the contents of every other slot")
(title :initarg :title :accessor title)
(body :initarg :body :accessor body)))
(defmethod (setf c2mop:slot-value-using-class) :after
(new class (object document) (slot c2mop:standard-effective-slot-definition))
;; To avoid this method triggering a call to itself, we check that the slot
;; the modification occurred in is not the slot we are updating.
(unless (eq (slot-definition-name slot) 'id)
(setf (slot-value object 'id) (hash-slots object))))
Należy pamiętać, że ponieważ podczas tworzenia instancji slot-value
nie jest wywoływana, może być konieczne zduplikowanie kodu w metodzie initialize-instance :after
(defmethod initialize-instance :after ((obj document) &key)
(setf (slot-value obj 'id)
(hash-slots obj)))