オブジェクトのスロットの値をまとめて変更する - lisp-cookbook-ja/common-lisp GitHub Wiki
オブジェクトのスロットの値は、初期化の際にまとめて設定することが可能です(オブジェクトの初期化を行う)が、生成した後にまとめて変更したい場合もあります。
この様な場合は、with-slots を利用するのが便利です。
(defclass tips-cl ()
(a b c d e))
(let ((obj (make-instance 'tips-cl)))
(with-slots (a b c d e) obj
(setq a 1
b 2
c 3
d 4
e 5))
(describe obj))
;-> #<TIPS-CL {100FBD6C63}>
; [standard-object]
;
; Slots with :INSTANCE allocation:
; A = 1
; B = 2
; C = 3
; D = 4
; E = 5
;
;=> <no values>
個別スロットの名前を指定するというより、オブジェクトのスロット全体を変更したい場合は、スロット名を取得し、slot-value で変更することになるでしょう。(MOPを利用します)
;; Closer to MOPの導入
(ql:quickload :closer-mop)
(let ((obj (make-instance 'tips-cl)))
(mapc (lambda (s)
(setf (slot-value obj (c2mop:slot-definition-name s))
:foo!))
(c2mop:class-slots (class-of obj)))
(describe obj))
;-> #<TIPS-CL {100FC71373}>
; [standard-object]
;
; Slots with :INSTANCE allocation:
; A = :FOO!
; B = :FOO!
; C = :FOO!
; D = :FOO!
; E = :FOO!
;
;=> <no values>
また slot-value を用いる方法よりは多少の制限がありますが、より高速なアクセスが期待される standard-instance-access を利用する方法もあります。
(let ((obj (make-instance 'tips-cl)))
(dotimes (idx (length (c2mop:class-slots (class-of obj))))
(setf (c2mop:standard-instance-access obj idx)
:foo!))
(describe obj))
;-> #<TIPS-CL {100FC71374}>
; [standard-object]
;
; Slots with :INSTANCE allocation:
; A = :FOO!
; B = :FOO!
; C = :FOO!
; D = :FOO!
; E = :FOO!
;
;=> <no values>