2010-09-01 20 views
4

Dans ma définition de classe, je souhaite initialiser un emplacement en fonction de la valeur d'un autre emplacement. Voici le genre de chose que je voudrais faire:Initialisation des emplacements en fonction d'autres valeurs de logement dans les définitions de classe de système Common Lisp Object

(defclass my-class() 
    ((slot-1 :accessor my-class-slot-1 :initarg slot-1) 
    (slot-2 :accessor my-class-slot-2 :initform (list slot-1)))) 

Toutefois, cela ne compile pas:

1 compiler notes: 

Unknown location: 
    warning: 
    This variable is undefined: 
     SLOT-1 

    warning: 
    undefined variable: SLOT-1 
    ==> 
     (CONS UC-2::SLOT-1 NIL) 


Compilation failed. 

Est-il possible de le faire?

Répondre

3

Utilisation initialize-instance :after documenté here

+0

Est-ce que ceci ou quelque chose d'équivalent est possible en utilisant des structures? – mck

2

Voici la réponse de Doug Currie a élargi:

(defclass my-class() 
    ((slot-1 :accessor my-class-slot-1 :initarg :slot-1) 
    (slot-2 :accessor my-class-slot-2))) 

(defmethod initialize-instance :after 
      ((c my-class) &rest args) 
    (setf (my-class-slot-2 c) 
     (list (my-class-slot-1 c)))) 

Voici un appel montrant que cela fonctionne:

> (my-class-slot-2 (make-instance 'my-class :slot-1 "Bob")) 
("Bob") 

Voir this article pour plus de détails.

+0

Zach Beane a également donné cette réponse (ou presque) sur comp.lang.lisp, mais je ne l'ai pas remarqué avant de taper mon propre code. Merci à tous les deux Zach et Doug! –

2
(defparameter *self-ref* nil) 


(defclass self-ref() 
() 

    (:documentation " 
Note that *SELF-REF* is not visible to code in :DEFAULT-INITARGS.")) 


(defmethod initialize-instance :around ((self-ref self-ref) &key) 
    (let ((*self-ref* self-ref)) 
    (when (next-method-p) 
     (call-next-method)))) 



(defclass my-class (self-ref) 
    ((slot-1 :accessor slot-1-of :initarg :slot-1) 
    (slot-2 :accessor slot-2-of 
      :initform (slot-1-of *self-ref*)))) 




CL-USER> (let ((it (make-instance 'my-class :slot-1 42))) 
      (values (slot-1-of it) 
        (slot-2-of it))) 
42 
42 
CL-USER>