[closer-devel] ContextL: allow other keys in (re)initialize-instance methods for metaclasses

Paul Sexton psexton.2a at gmail.com
Fri Mar 16 00:32:29 UTC 2012


Thanks -- I have figured out how to stop the error from occurring, but
I now have a different problem: the initargs for classes other than
layered-class seem to get ignored and do not result in values being
stored in the class' slots.

Here is a simple example.
---------------------
(use-package :closer-mop)

(defclass serializable-class (standard-class)
  ((database :initarg :database)))

(defclass dummy-class (standard-class)
  ())

;; "layered serializable" metaclass
(defclass combined-class1 (contextl:layered-class serializable-class)
  ())

;; another metaclass for comparison. Only difference is it inherits
from dummy-class instead of layered-class.
(defclass combined-class2 (dummy-class serializable-class)
  ())

(defmethod validate-superclass ((class combined-class1) (superclass
standard-class))
  t)

(defmethod validate-superclass ((class combined-class2) (superclass
standard-class))
  t)

;; Trying to create a class that uses serializable-class as its metaclass causes
;; the error "invalid initialisation argument :DATABASE"
(defclass try1 ()
  ()
  (:metaclass combined-class1)
  (:database . "mydb"))

;; So we define the following methods to disable checking of initargs...
(defmethod initialize-instance :around ((c combined-class1) &rest args)
  (if (next-method-p)
      (apply #'call-next-method c :allow-other-keys t args)))

(defmethod reinitialize-instance :around ((c combined-class1) &rest args)
  (if (next-method-p)
      (apply #'call-next-method c :allow-other-keys t args)))

;; Now (defclass try1) works ... but 'database' slot of the resulting
class is unbound.

;; In contrast, if we define basically the same :around methods for
;; combined-class2:
(defmethod initialize-instance :around ((c combined-class2) &rest args)
  (if (next-method-p)
      (apply #'call-next-method c :allow-other-keys t args)))

(defmethod reinitialize-instance :around ((c combined-class2) &rest args)
  (if (next-method-p)
      (apply #'call-next-method c :allow-other-keys t args)))

;; ...And create a class with class2 as its metaclass...
(defclass try2 ()
  ()
  (:metaclass combined-class2)
  (:database . "mydb"))

;; Then this works. The resulting class has its :database slot correctly
;; bound to the value "mydb"

The most obvious explanation is that contextl is somehow discarding
keyword args that it does not recognise, preventing them from being
seen by other initialisation methods. Is there an alternative
explanation I am missing?

On 16 March 2012 07:59, Pascal Costanza <pc at p-cos.net> wrote:
> Hi Paul,
>
> I'm hesitating to make such a change, because it would weaken checking initialization arguments for validity.
>
> Under normal circumstances, it is possible to make more initialization arguments valid for subclasses. See Section 7.1.2 of the HyperSpec. This also applies to metaobject classes. If for some reason this doesn't work for you, I would like to know about it and see whether something needs to be fixed. Please send some example, and some information which CL implementation you are using to test this.
>
> Pascal
>
> P.S.: I'm curious to hear about what you use ContextL for, and what you are adding in your subclasses. If you prefer, please feel free to contact me by private email on this. Thanks.
>
> On 14 Mar 2012, at 21:56, Paul Sexton wrote:
>
>> Hi
>>
>> At present the metaclasses in contextl choke during initialisation if
>> they are passed keys that they do not recognise. This makes it very
>> difficult to create metaclasses derived from those classes, if the
>> derived metaclasses need to be passed their own arguments a la
>> ':in-layer'.
>>
>> Including &allow-other-keys in the argument lists for
>> (re)initialize-instance in cx-classes-in-layer.lisp and
>> cx-layer-metaclasses.lisp seems to fix this, and doesn't seem to have
>> any downsides. Would you consider making this change?
>>
>> Thanks
>> Paul
>>
>> _______________________________________________
>> closer-devel mailing list
>> closer-devel at common-lisp.net
>> http://lists.common-lisp.net/cgi-bin/mailman/listinfo/closer-devel
>
> --
> Pascal Costanza
>
>
>




More information about the closer-devel mailing list