Q: how can I pass an argument to an object constructor that won't be interpreted as a slot?

I am creating an instance of a class. The value of one of its slots depends on another slot and auxiliary information not contained in the class itself.

I have written an after method for initialize-instance, as in the toy example below:

(defvar testvar '((a . "a value")
                  (b . "b value")))

(defclass testclass ()
    :initarg :slot-1
    :initform nil
    :accessor get-slot1)
    :initform nil
    :accessor get-slot2))
  "Toy class.")

(cl-defmethod initialize-instance :after ((test testclass) &key)
  (with-slots (slot-1 slot-2) test
    (setf slot-2 (cdr (assq slot-1 testvar)))))

In the example, the value of slot-2 depends on the value of slot-1, which requires looking up something in auxiliary alist testvar. Accordingly:

(setq var1 (testclass :slot-1 'a)
      var2 (testclass :slot-1 'b))
(get-slot2 var1)                        ; => "a value"
(get-slot2 var2)                        ; => "b value"

That's all well and good, but: to do this, I have to create and access a global variable testvar. How can I do this without using a global variable? How can I pass another argument to the testclass constructor (or initialize-instance) that contains the relevant alist without it being interpreted as a slot value?

(I'm exploring elisp's OO facilities, so there's a decent chance I'm missing something obvious.)

  • EIEIO is closely modeled on CLOS, so you may want to see how it's done in Common-Lisp. Personally I stay away from defclass and stick to cl-defstruct instead. – Stefan Feb 11 at 14:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.