common-lisp
CLOS Meta-objektprotokoll
Sök…
Skaffa platserna för en klass
Låt oss säga att vi har en klass som
(defclass person ()
(name email age))
För att få namnen på klassens platser använder vi funktionsklassplatserna. Detta kan hittas i närmopppaketet, som tillhandahålls av systemet närmare mop. För att ladda den den löpande lisp-bilden vi använder (ql:quickload :closer-mop)
. Vi måste också se till att klassen slutförs innan vi ringer klassplatser.
(let ((class (find-class 'person)))
(c2mop:ensure-finalized class)
(c2mop:class-slots class))
som returnerar en lista med effektiva slotdefinitionsobjekt :
(#<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>)
Uppdatera en plats när en annan plats ändras
CLOS MOP tillhandahåller klassen med spårvärdevärde, som kallas när ett kortplats har värde, åtkomst eller läsning. Eftersom vi bara tar hand om modifieringar i detta fall definierar vi en metod för (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))))
Observera att eftersom det till exempel inte skapas slot-value
kan det vara nödvändigt att kopiera koden i initialize-instance :after
metoden
(defmethod initialize-instance :after ((obj document) &key)
(setf (slot-value obj 'id)
(hash-slots obj)))