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

August 17, 2014

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

このタイトルで續けるかどうか疑問ではあるが、オブジェクト指向についてもう少し考えてみる。いきなりエイエイオーするには、まだまだ頭の中が整理出來ていないような氣がするからだ。ちなみにMeadow(Emacs-22.3)では、eieioはcedetパッケージの一部としてpackages/lisp/cedet/eieioにあるが、最新のEmacs-24.4.50ではlisp/emacs-lispに混入されている。つまり外部Lispではなく普通に「part of GNU Emacs」になっている。ということはEmacsのlispディレクトリが今後どんどんOOP化していくかもしれず?だとすればOOPに無關心ではいられなくなっていくわけだ

(require 'cl)

(makunbound 'test-object)

(defun tiki-object-search (obj)
  (assq 'data obj))

(defun tiki-object-add (obj key1 key2 &optional sym)
  (setf (cdr obj)
	(append
	 (cdr obj)
	 (list (cons
		(list key1 key2)
		(or sym
		    (intern (read-from-minibuffer "STRING: "))))))))

(defun tiki-object-run (key1 key2 &optional sym)
  (let* ((obj (tiki-object-search test-object))
	 (answer (assoc (list key1 key2) (cadr obj))))
    (if answer (cdr answer)
      (tiki-object-add obj key1 key2 sym))))

(defun tiki-def-method (tag func)
  (let* ((method (assq tag test-object)))
    (if method (setf (cdr method) func)
      (add-to-list 'test-object (cons tag func)))))

(setq test-object
      '((data (((man woman) . love)
	       ((oldman sea) . anekdoten)))
	(method . tiki-def-method)))

(funcall (cdr (assq 'method test-object)) 'search 'tiki-object-search)
(funcall (cdr (assq 'method test-object)) 'add 'tiki-object-add)
(funcall (cdr (assq 'method test-object)) 'run 'tiki-object-run)

(print test-object)
((run . tiki-object-run)
 (add . tiki-object-add)
 (search . tiki-object-search)
 (data (((man woman) . love)
	((oldman sea) . anekdoten)))
 (method . tiki-def-method))

(defun test-object::run (key1 key2 &optional sym)
  (funcall (cdr (assq 'run test-object)) key1 key2 sym))

(test-object::run 'oldman 'sea)
anekdoten

「プログラミングを始めるには(15)」で書いたインチキ臭いプログラムを少し直してみた。この方が少しはマシなカプセル化になっているのではないかと思われる。で、別に最初から仕組んだ流れではないが、次に試すべきはdefstructだろうと思う。

(require 'cl)

(defstruct test-object data add run)

(setf test-instance
      (make-test-object :data '(((man woman) . love)
				((oldman sea) . anekdoten))
			:add nil
			:run nil))
					    
(setf (test-object-add test-instance)
      (function
       (lambda (data key1 key2 &optional sym)
	 (setf (test-object-data test-instance)
	       (append
		data
		(list (cons
		       (list key1 key2)
		       (or sym
			   (intern
			    (read-from-minibuffer "STRING: "))))))))))

(setf (test-object-run test-instance)
      (function
       (lambda (key1 key2 &optional sym)
	 (let* ((data (test-object-data test-instance))
		(answer (assoc (list key1 key2) data)))
	   (if answer (cdr answer)
	     (funcall (test-object-add test-instance) data key1 key2 sym))))))

(funcall (test-object-run test-instance) 'oldman 'sea)
anekdoten

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

このようにかなりすっきりするが、試した限りではedebugで追いかけることが出來ない?ようだ。やはり無名關數ではデバグ出來なさそうである。それと、インスタンスを作ってから出ないとアクセスするデータが決まらないので、メソッドは後からsetfを使ってスロットに設定してやらないといけない。さらに、スロットは動的にオーバーライド出來るが、動的に增やすことは出來ない?のではないか。おそらくこうした問題はdefclassを使ったOOPでは解決されているものと思われる。

ところで、こうして自力でカプセル化もどきの試行錯誤をやっていて、今までの自分のプログラムの書き方を少し變えてみようという氣になった。正直言って、會社で動かしているelispのバッチ處理は贔屓目に見ても綺麗じゃない。畫面を縱いっぱいに引き延ばしても2畫面以上あるような大きな關數を平氣で書いていた。だが、エイエイオーを使うにはまだいくつかハードルがあるような氣がする。

|

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

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/60164748

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

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