[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

looking for initargs of make-instance

At  5:35 PM 7/5/93 +0000, Karsten Poeck wrote:
>In article <9307051608.AA21343@cambridge.apple.com>,
>bill@cambridge.apple.com (Bill St. Clair) wrote:
>> (ccl::class-make-instance-initargs class)
>> returns a list of the valid initargs for (make-instance class).
>> The "class" argument can be a class or a symbol naming a class.
>This does not works for me if I have specified a &key &allow-other-keys in
>the initialize-instance: e.g.
>(defclass test (window)
>  ())
>(defmethod initialize-instance ((ich test)
>                                &rest init-list
>                                &key &allow-other-keys)
>  (declare (ignore init-list))
>  )
>(ccl::class-make-instance-initargs (find-class 'test))
>> Error: value T is not of the expected type Sequence.
>> While executing: Ccl::Concat-To-List*
>> Type Command-. to abort.
>See the RestartsI menu item for further choices.

You have discovered that CLASS-MAKE-INSTANCE-INITARGS has not been
tested very much. MCL doesn't use it (though it does use the
functions that it calls). In this case, all initargs will be accepted
due to the &ALLOW-OTHER-KEYS in your INITIALIZE-INSTANCE method. Load
the included patch, and your CLASS-MAKE-INSTANCE-INITARGS call will
return T instead of signalling an error.

>ccl::class-make-instance-initargs would be extremly usefull for us,
>if it would work for this situation also. Normally we build nested
>where the outermost dialog-item gets all the initargs, filters then and
>passes them to the inner dialog-items. 
>Do you have a hint how we could extend ccl::class-make-instance-initargs to
>this situation

Here is MCL's code that figures out the valid initargs. Sounds as if
you want a modified version of COMPUTE-INITARGS-VECTGOR that doesn't
treat &ALLOW-OTHER-KEYS ($LFBITS-AOK-BIT) specially. Note that this
code is likely to change in future versions of MCL (though I have no
plans to change it for MCL 3.0). Note that this code caches its
results in special slots in the class. If you want to cache your
results, you can use the CCL::%CLASS-ALIST, accessed via


(in-package :ccl)

(require "LISPEQU")    ; for $lfbits-aok-bit

(defun initargs-vector (instance class functions)
  (let ((index (cadr (assq (car functions) *initialization-invalidation-alist*))))
    (unless index
      (error "Unknown initialization function: ~s." (car functions)))
    (let ((initvect (%svref class index)))
      (unless initvect
        (setf (%svref class index) 
              (setq initvect (compute-initargs-vector instance class functions))))

(defun compute-initargs-vector (instance class functions)
  (let ((initargs (class-slot-initargs class))
        (cpl (%inited-class-cpl class)))
    (dolist (f functions)         ; for all the functions passed
      (dolist (method (%gf-methods f))   ; for each applicable method
        (let ((spec (car (%method-specializers method))))
          (when (if (listp spec)
                  (eql instance (cadr (the list spec)))
                  (memq spec cpl))
            (let* ((func (%inner-method-function method))
                   (keyvect (if (logbitp $lfbits-aok-bit (lfun-bits func))
                              (return-from compute-initargs-vector t)
                              (lfun-keyvect func))))
              (dovector (key keyvect)
                (pushnew key initargs)))))))   ; add all of the method's keys
    (apply #'vector initargs)))

; A useful function
(defun class-make-instance-initargs (class)
  (setq class (require-type (if (symbolp class) (find-class class) class)
  (flet ((iv (class &rest functions)
           (declare (dynamic-extent functions))
           (initargs-vector (class-prototype class) class functions)))
    (let ((initvect (apply #'iv
                           #'initialize-instance #'allocate-instance #'shared-initialize
                           (aux-init-functions class))))
      (if (eq initvect 't)   ; This test was added in "initargs-patch".
        (concatenate 'list initvect)))))

(This file must be converted with BinHex 4.0)