common-lisp
Protocollo Meta-Object CLOS
Ricerca…
Ottieni i nomi degli slot di una classe
Diciamo che abbiamo una classe come
(defclass person ()
(name email age))
Per ottenere i nomi degli slot della classe usiamo le slot di classe delle funzioni. Questo può essere trovato nel pacchetto closer-mop, fornito dal sistema più vicino-mop. Per caricarlo l'immagine lisp corrente che usiamo (ql:quickload :closer-mop)
. Dobbiamo anche assicurarci che la classe sia finalizzata prima di chiamare le slots di classe.
(let ((class (find-class 'person)))
(c2mop:ensure-finalized class)
(c2mop:class-slots class))
che restituisce un elenco di oggetti di definizione di slot efficaci :
(#<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>)
Aggiorna uno slot quando viene modificato un altro slot
Il MOP di CLOS fornisce la classe di utilizzo del valore di slot hook, che viene richiamata quando si accede a un valore di slot, si legge o si modifica. Poiché in questo caso ci interessano solo le modifiche, definiamo un metodo per (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))))
Si noti che poiché all'istanza non viene richiamato lo slot-value
creazione, potrebbe essere necessario duplicare il codice initialize-instance :after
metodo
(defmethod initialize-instance :after ((obj document) &key)
(setf (slot-value obj 'id)
(hash-slots obj)))