(defvar *invoices* (ds:make-dictionary)) ;;; WAY 1 (defgeneric make-inst (class &rest initargs &key customize &allow-other-keys)) (defmethod make-inst (class &rest initargs &key (customize t) &allow-other-keys) (apply #'make-instance class :customize customize initargs)) (defmethod initialize-instance :around ((inv invoice:invoice) &rest initargs &key customize &allow-other-keys) (let ((instance (call-next-method))) (when customize (ds:insert instance *invoices*)) instance)) (make-instance 'invoice:standard-invoice) (make-inst 'invoice:standard-invoice) ; creates an instance and also populates *invoices* ;;; WAY 2 which I think is not as good (defgeneric make-invoice (class &rest initargs &key &allow-other-keys)) (defgeneric make-inst (class &rest initargs &key &allow-other-keys)) (defmethod make-inst (class &rest initargs &key &allow-other-keys) (apply (cond ((subtypep class 'invoice:invoice) #'make-invoice) (t #'make-instance)) class initargs)) (defmethod make-invoice :around (class &rest initargs &key &allow-other-keys) (let ((instance (call-next-method))) (ds:insert instance *invoices*)))