| 1 | (defclass foo-class (standard-class)
|
|---|
| 2 | ())
|
|---|
| 3 |
|
|---|
| 4 | ;;;
|
|---|
| 5 | ;;; Issue 1:
|
|---|
| 6 | ;;;
|
|---|
| 7 | ;;; It seems ABCL doesn't require an implementation of this method
|
|---|
| 8 | ;;; for metaclasses to work properly? It's definitely needed on SBCL
|
|---|
| 9 | ;;; and the closer-mop package provides it.
|
|---|
| 10 | ;;;
|
|---|
| 11 | ;;; It's commented out in order to make the program run.
|
|---|
| 12 | ;;;
|
|---|
| 13 | #+nil(defmethod mop:validate-superclass ((class foo-class) (superclass standard-object))
|
|---|
| 14 | t)
|
|---|
| 15 |
|
|---|
| 16 | (defclass foo-slot-mixin ()
|
|---|
| 17 | ((field-data :initarg :field-data
|
|---|
| 18 | :initform 'abc
|
|---|
| 19 | :accessor field-data)))
|
|---|
| 20 |
|
|---|
| 21 | (defclass foo-direct-slot-definition (foo-slot-mixin mop:standard-direct-slot-definition)
|
|---|
| 22 | ())
|
|---|
| 23 |
|
|---|
| 24 | (defclass foo-effective-slot-definition (foo-slot-mixin mop:standard-effective-slot-definition)
|
|---|
| 25 | ())
|
|---|
| 26 |
|
|---|
| 27 | ;;;
|
|---|
| 28 | ;;; Issue 2:
|
|---|
| 29 | ;;;
|
|---|
| 30 | ;;; The following two methods require me to use the double-: as they
|
|---|
| 31 | ;;; are not exported.
|
|---|
| 32 | ;;;
|
|---|
| 33 | (defmethod mop::direct-slot-definition-class ((class foo-class) &rest initargs)
|
|---|
| 34 | (format t "getting dir class. initargs=~s~%" initargs)
|
|---|
| 35 | (find-class 'foo-direct-slot-definition))
|
|---|
| 36 |
|
|---|
| 37 | (defmethod mop::effective-slot-definition-class ((class foo-class) &rest initargs)
|
|---|
| 38 | (format t "getting eff class. initargs=~s~%" initargs)
|
|---|
| 39 | (find-class 'foo-effective-slot-definition))
|
|---|
| 40 |
|
|---|
| 41 | ;;;
|
|---|
| 42 | ;;; Issue 3:
|
|---|
| 43 | ;;;
|
|---|
| 44 | ;;; Similar to issue 2, I need to use double-: here.
|
|---|
| 45 | ;;;
|
|---|
| 46 | (defmethod mop::compute-effective-slot-definition ((class foo-class) slot-name direct-slots)
|
|---|
| 47 | (format t "computing slot definition: class=~s name=~s slots=~s~%"
|
|---|
| 48 | class slot-name direct-slots)
|
|---|
| 49 | (let ((result (call-next-method)))
|
|---|
| 50 | (format t " result: ~s~%" result)
|
|---|
| 51 | result))
|
|---|
| 52 |
|
|---|
| 53 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|---|
| 54 |
|
|---|
| 55 | (defclass bar ()
|
|---|
| 56 | ((value :initarg :value
|
|---|
| 57 | :accessor bar-value
|
|---|
| 58 | :field-data 'some-value))
|
|---|
| 59 | (:metaclass foo-class))
|
|---|
| 60 |
|
|---|
| 61 | (defun test-metaclass ()
|
|---|
| 62 | ;;
|
|---|
| 63 | ;; Issue 4:
|
|---|
| 64 | ;;
|
|---|
| 65 | ;; The following call to MAKE-INSTANCE will fail with an error saying that :VALUE
|
|---|
| 66 | ;; is not a valid initialiser:
|
|---|
| 67 | ;;
|
|---|
| 68 | ;; Invalid initarg :VALUE.
|
|---|
| 69 | ;; [Condition of type PROGRAM-ERROR]
|
|---|
| 70 | ;;
|
|---|
| 71 | (let ((v (make-instance 'bar :value 10)))
|
|---|
| 72 | ;;
|
|---|
| 73 | ;; Issue 5:
|
|---|
| 74 | ;;
|
|---|
| 75 | ;; If I comment out the ":value 10" part above, in order to get the thing to run,
|
|---|
| 76 | ;; the below code will return NIL. It appears MOP:CLASS-SLOTS returns NIL
|
|---|
| 77 | ;; instead of a list of slots.
|
|---|
| 78 | ;;
|
|---|
| 79 | (dolist (s (mop:class-slots (class-of v)))
|
|---|
| 80 | (format t "slot ~s = ~s~%"
|
|---|
| 81 | (mop:slot-definition-name s)
|
|---|
| 82 | ;; The below dereferencing of the FIELD-DATA slot causes the following error:
|
|---|
| 83 | ;;
|
|---|
| 84 | ;; The slot FIELD-DATA is unbound in the object #<FOO-EFFECTIVE-SLOT-DEFINITION VALUE>.
|
|---|
| 85 | ;; [Condition of type UNBOUND-SLOT]
|
|---|
| 86 | (field-data s)))))
|
|---|