« プログラミングを始めるには(18) | Main | プログラミングを始めるには(20) »

August 17, 2014

プログラミングを始めるには(19)

defstructの次はdefclassを用いて、このところずーっとやっている同じ例題を書いてみたが...結局は期待外れだったようだ。

(require 'cl)

(defclass test-class ()
  ((data :initarg data
	 :reader test-reader
	 :accessor test-writer
	 :initform '(((man woman) . love) ((oldman sea) . anekdoten)))))

(setq test-obj (make-instance 'test-class))

(defun test-add (key1 key2 &optional sym)
  (setf (test-writer test-obj)
	(append
	 (test-reader test-obj)
	 (list (cons
		(list key1 key2)
		(or sym
		    (intern
		     (read-from-minibuffer "STRING: "))))))))

(defun test-run (key1 key2 &optional sym)
  (let* ((data (test-reader test-obj))
	 (answer (assoc (list key1 key2) data)))
    (if answer (cdr answer)
      (test-add key1 key2 sym))))

(test-run 'man 'woman)
love

(test-run 'oldman 'sea)
anekdoten

(test-run 'mon 'son)
(((man woman) . love) ((oldman sea) . anekdoten) ((mon son) . sexy))

これだったらdefstructでも同じじゃないの?という氣がする。アクセサを自動生成する分、defstructの方がマシかも。クラスオプションに:writerでスロットへの書き込みアクセサを指定すると、實行時にエラーになる。Infoには:readerもエラーになるようなことが書かれているが、readerの方は動くようだ。ただしreaderが本當にリードオンリーかどうかまでは確認していない。とりあえずwriterはaccessorと同じにしておけば良いと思うが、そういうところだけは嚴密に考えるのか。

これでデータと機能をカプセル化したことになるのか甚だ疑問が殘る。それとインスタンスがどちらもベクトルというのも氣になる。心殘りはdefmethodの實用的な使い方がどこにもなかったこと。どのような動作をするかを示す簡單な例しかネット上に無かったのが不思議。結局、最初に書いたインチキ臭いカプセル化が一番自分のイメージと一致していたという皮肉な結果に終わったようだ。

(require 'cl)

(defclass test-class ()
  ((data :initarg data
	 :accessor test-data
	 :initform '(((man woman) . love) ((oldman sea) . anekdoten)))
   (keyw :initarg keyw
	 :accessor test-keyw
	 :initform nil)
   (answ :initarg answ
	 :accessor test-answ
	 :initform nil)))

(setf test-obj (make-instance test-class))

(defun test-add (answ)
  (setf (test-data test-obj)
	(append
	 (test-data test-obj)
	 (list (cons
		(test-keyw test-obj)
		(or answ
		    (intern (read-from-minibuffer "STRING: "))))))))

(defun test-run (key1 key2 &optional answ)
  (setf (test-keyw test-obj) (list key1 key2))
  (setf (test-answ test-obj)
	(cdr (assoc (test-keyw test-obj) (test-data test-obj))))
  (or (test-answ test-obj) (test-add answ)))

(test-run 'man 'woman)
love

(test-run 'oldman 'sea)
anekdoten

(test-run 'mom 'son)
(((man woman) . love) ((oldman sea) . anekdoten) ((mom son) . sexy))

(test-run 'mom 'son)
sexy

test-obj
[object test-class "test-class"
	(((man woman) . love)
	 ((oldman sea) . anekdoten)
	 ((mom son) . sexy))
	(mom son) sexy]

どうせならこうしてはどうかと考えたのが上記の書き方。一應再入するスレッドが無い前提。普通ならローカルバインディングにするような變數も、オブジェクトに持たせてしまえという方針である。こうすると處理が終わった後にいろんな中閒データが殘るので、デバグの役にも立ちそうな氣がする。これでこの例でのOOPの檢討は終わりにする。

|

« プログラミングを始めるには(18) | Main | プログラミングを始めるには(20) »

Comments

Post a comment



(Not displayed with comment.)


Comments are moderated, and will not appear on this weblog until the author has approved them.



TrackBack

TrackBack URL for this entry:
http://app.cocolog-nifty.com/t/trackback/74224/60166335

Listed below are links to weblogs that reference プログラミングを始めるには(19):

« プログラミングを始めるには(18) | Main | プログラミングを始めるには(20) »