0

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 ()
  ((slot-1
    :initarg :slot-1
    :initform nil
    :accessor get-slot1)
   (slot-2
    :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 acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Browse other questions tagged or ask your own question.