Problem
Given an instance, inst and a string attr containing the name of a slot, how can I obtain the value of the slot attr on inst?
Of course, if attr were a symbol rather than a string, I would typically just use (slot-value inst attr), but it seems I need the package information to properly call intern (see below).
Minimal example
(defpackage :pack1
(:use :common-lisp)
(:export :*inst*))
(in-package :pack1)
(defclass temp-class ()
((temp-slot :initarg :temp-slot)))
(defvar *inst* (make-instance 'temp-class :temp-slot "value"))
(defpackage :pack2
(:use :common-lisp :pack1)
(:import-from :pack1 :temp-class))
(in-package :pack2)
(let ((inst *inst*) ; In the real example, inst gets defined outside my control,
; in yet another package
(attr "temp-slot"))
(format t "Given package name: ~S; " ; prints fine
(slot-value inst (intern (string-upcase attr) :pack1)))
(format t "No package name: ~S; " ; signals an error
(slot-value inst (intern (string-upcase attr)))))
Prior art
- From this question, I figured out that my problem was that
internwas creating symbols in a different package than the one in which the class was defined. - It seems from this question, that I can't extract the package information simply from the instance, so I'll have to figure out another way (besides using
internto get there)
Background
I'm working on py-format a Common Lisp port of
Python's {}-formatting. To implement the Python . operator (getattr) I need to convert the
string following the dot into a slot on the object preceding the dot.