Shammer's Philosophy

My private adversaria

CLOSエクササイズ第03回

defclassで指定できるパラメータは、CLHS: Macro DEFCLASSなどに説明がある。これはマクロだったのか。あるフィールドの型を別のクラスにする、という例。このためには:typeを使用してフィールド(Common Lisp ではスロットというらしい)を定義すればよい。

(defclass user ()
  ((name :accessor user-name :initarg :name)
   (pass :accessor user-password)
   (age  :accessor user-age)))

(defclass subject ()
  ((principal :accessor subject-principal :type user)))  

使用例は以下。

(defparameter user-0 (make-instance 'user))
(setf (user-name user-0) "Taro")
(format t "User-0 Name is ~A.~%" (user-name user-0))


(defparameter subject-0 (make-instance 'subject))
(setf (subject-principal subject-0) user-0)
(format t "Subject-0 principal is ~A.~%" (subject-principal subject-0))

(defparameter error-subject-0 (make-instance 'subject))
(format t "Created error-subject-0.~%")
(setf (subject-principal error-subject-0) 'a);Error

一番最後の行でエラーが出るはず。以下、実行結果。

User-0 Name is Taro.
Subject-0 principal is #<USER #x302000C2E46D>.
Created error-subject-0.
> Error: The value A can not be used to set the value of the slot PRINCIPAL in #<SUBJECT #x302000C5C60D>, because it is not of type USER. 
> While executing: CCL::%MAYBE-STD-SETF-SLOT-VALUE-USING-CLASS, in process listener(1).
> Type :GO to continue, :POP to abort, :R for a list of available restarts.
> If continued: Skip loading "user-handle.lisp"
> Type :? for other options.
1 >