-(defmethod shared-initialize
- ((instance slot-object) slot-names &rest initargs)
- (cond
- ((eq slot-names t)
- (call-initialize-function
- (initialize-info-shared-initialize-t-fun
- (initialize-info (class-of instance) initargs))
- instance initargs))
- ((eq slot-names nil)
- (call-initialize-function
- (initialize-info-shared-initialize-nil-fun
- (initialize-info (class-of instance) initargs))
- instance initargs))
- (t
- ;; Initialize the instance's slots in a two step process:
- ;; (1) A slot for which one of the initargs in initargs can set
- ;; the slot, should be set by that initarg. If more than
- ;; one initarg in initargs can set the slot, the leftmost
- ;; one should set it.
- ;; (2) Any slot not set by step 1, may be set from its initform
- ;; by step 2. Only those slots specified by the slot-names
- ;; argument are set. If slot-names is:
- ;; T
- ;; then any slot not set in step 1 is set from its
- ;; initform.
- ;; <list of slot names>
- ;; then any slot in the list, and not set in step 1
- ;; is set from its initform.
- ;; ()
- ;; then no slots are set from initforms.
- (flet ((initialize-slot-from-initarg (class instance slotd)
- (let ((slot-initargs (slot-definition-initargs slotd)))
- (doplist (initarg value) initargs
- (when (memq initarg slot-initargs)
- (setf (slot-value-using-class class instance slotd)
- value)
- (return t)))))
- (initialize-slot-from-initfunction (class instance slotd)
- (unless (or (slot-boundp-using-class class instance slotd)
- (null (slot-definition-initfunction slotd)))
- (setf (slot-value-using-class class instance slotd)
- (funcall (slot-definition-initfunction slotd)))))
- (class-slot-p (slotd)
- (eq :class (slot-definition-allocation slotd))))
- (loop with class = (class-of instance)
- for slotd in (class-slots class)
- unless (or (class-slot-p slotd)
- (initialize-slot-from-initarg class instance slotd))
- when (memq (slot-definition-name slotd) slot-names) do
- (initialize-slot-from-initfunction class instance slotd))
- instance))))
+(defmethod shared-initialize ((instance slot-object) slot-names &rest initargs)
+ (flet ((initialize-slot-from-initarg (class instance slotd)
+ (let ((slot-initargs (slot-definition-initargs slotd)))
+ (doplist (initarg value) initargs
+ (when (memq initarg slot-initargs)
+ (setf (slot-value-using-class class instance slotd)
+ value)
+ (return t)))))
+ (initialize-slot-from-initfunction (class instance slotd)
+ ;; CLHS: If a before method stores something in a slot,
+ ;; that slot won't be initialized from its :INITFORM, if any.
+ (if (typep instance 'structure-object)
+ (when (eq (funcall
+ ;; not SLOT-VALUE-USING-CLASS, as that
+ ;; throws an error if the value is the
+ ;; unbound marker.
+ (slot-definition-internal-reader-function slotd)
+ instance)
+ +slot-unbound+)
+ (setf (slot-value-using-class class instance slotd)
+ (let ((initfn (slot-definition-initfunction slotd)))
+ (when initfn
+ (funcall initfn)))))
+ (unless (or (null (slot-definition-initfunction slotd))
+ (slot-boundp-using-class class instance slotd))
+ (setf (slot-value-using-class class instance slotd)
+ (funcall (slot-definition-initfunction slotd)))))))
+ (let* ((class (class-of instance))
+ (initfn-slotds
+ (loop for slotd in (class-slots class)
+ unless (initialize-slot-from-initarg class instance slotd)
+ collect slotd)))
+ (dolist (slotd initfn-slotds)
+ (if (eq (slot-definition-allocation slotd) :class)
+ (when (or (eq t slot-names)
+ (memq (slot-definition-name slotd) slot-names))
+ (unless (slot-boundp-using-class class instance slotd)
+ (initialize-slot-from-initfunction class instance slotd)))
+ (when (or (eq t slot-names)
+ (memq (slot-definition-name slotd) slot-names))
+ (initialize-slot-from-initfunction class instance slotd)))))
+ instance))