Common Lispのdefstructのスロットの:read-onlyオプションについて
defstructのスロットに:read-onlyオプションを付けますが、SBCL等ではスロットに書き込めてしまいます。 他の処理系では、セッターを定義しないことで書き込みをしにくくしているようですが、 なにかもっと良い方法はないのでしょうか。
(defstruct foo (x nil :read-only t) y z)
(setf (foo-x (make-foo :x 9)) 8)
;sbcl => 8
;!> allegro: `(SETF FOO-X)' is not fbound
;!> ecl: The function (SETF FOO-X) is undefined.
;!> clisp: FUNCALL: undefined function |(SETF COMMON-LISP-USER:FOO-X)|
;; ※ANSI CL仕様外
(setf (slot-value (make-foo :x 9) 'x) 8)
;=> 8
エラーを出すようセッターを定義する位しかないのでしょうか。
(defun (setf foo-x) (val foo)
(declare (ignore val))
(error "~S: attempt to write a readonly slot: X" foo))
;; ※ANSI CL仕様外
(defmethod (setf c2mop:slot-value-using-class)
(val
(class (eql (find-class 'foo)))
(obj foo)
(slotd
(eql
(find 'x (c2mop:class-slots (find-class 'foo))
:key #'c2mop:slot-definition-name))))
(error "~S: attempt to write a readonly slot: X" obj))