Hatena::Groupcadr

わだばLisperになる このページをアンテナに追加 RSSフィード

2004 | 12 |
2005 | 01 | 02 | 07 | 10 | 11 |
2006 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2007 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2008 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2009 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2010 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2011 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 11 |

2007-12-11

CLOSチュートリアル (6)

| 15:18 | CLOSチュートリアル (6) - わだばLisperになる を含むブックマーク はてなブックマーク - CLOSチュートリアル (6) - わだばLisperになる

Common Lisp クックブックさんのところのCLOSのチュートリアルに新しい練習問題(CLOSチュートリアル - 4.4. すべてはオブジェクトの中にあるCLOSチュートリアル - 4.5. その他の特定子(まだCLOSオブジェクトは不要です))が出たので挑戦!。

4.4 問題.1

Lispの describe 関数は、処理中に describe-object 総称関数を呼び出します。各処理系は各クラスにこのメソッドを実装する必要があり(ただし、standard-object 以外のクラスへの実装は任意です。また、ユーザは自由にメソッドを追加して構いません)、このメソッドがオブジェクトとストリームの二つの引数を受け取るように実装しています。実装者が describe-object のすべてのメソッドを一つのファイルに書くべきか、複数のファイルに分散して書くべきか議論しなさい(例えば、aardvark で特定化されるメソッドを、クラス定義と他のメソッドと一緒に "aardvark.lisp" ファイルに書くべきかどうか)。で、どんな意見が出ましたか?

4.4 解答.1

他のオジェクト指向言語を触ったことがないので、普通がどういうものなのか良く分からないのですが、分けて書けてしまうということは、分けて書いた方が分かりやすいような使い方もできてしまうということかもしれず、別に全部一つに纏める必要はないんじゃないかと思う。

4.4 問題.2

二番目以降の複数の引数でメソッドを特定化しなければならない例をいくつか考えなさい。

4.4 解答.2

(defmethod concat ((str string) (num number))
  (concatenate 'string str (princ-to-string num)))

(defmethod concat ((num number) (str string))
  (concatenate 'string (princ-to-string num) str))

(defmethod concat ((n1 number) (n2 number))
  (concatenate 'string (princ-to-string n1) (princ-to-string n2)))

(defmethod concat ((s1 string) (s2 string))
  (concatenate 'string s1 s2))

とかどうだろう。ちょっと無理矢理な気もするけれど…。本当は可変長の引数が取れるようにしてみたかったけど、defmethodと&restの組み合わせの定番処理方法がいまいち良く分からず…。

4.5 問題.1

リストのための my-describe メソッドを書きなさい。

4.5 解答.1

(defmethod my-describe ((list list))
  (format t "~S is a list object~:[~;and a null object~]." list (null list)))

listは、nil+consなので、nilの場合に追加メッセージを表示するようにしてみた。

4.5 問題.2

antelope クラスのインスタンス Eric のための print-object メソッドを書きなさい。Eric のクラスを変更しても、そのメソッドはまだ適用可能だと思いますか?

4.5 解答.2

(defmethod print-object ((antelope antelope) stream)
  (print-unreadable-object (antelope stream :type 'T :identity 'T)
    (princ "[Hello, Antelope!]")))

Ericのクラスを変更してメソッドの挙動を確認

(class-of Eric)
;=> #<STANDARD-CLASS ANTELOPE>

(print-object eric t)
;=> #<ANTELOPE [Hello, Antelope!] #x300041D3065D>

(change-class eric 'aardvark)
;#<STANDARD-CLASS AARDVARK>

(print-object eric t)
;=> #<AARDVARK #x300041D3065D>

ということで、クラス変更によりantelopeの特定化からは外れた様子。