[SML 7177] Re: "0 @ 0" について
Osamu Hamasaki
osamu_hamasaki @ nifty.com
2006年 9月 24日 (日) 11:27:37 JST
濱崎です。
寺内さん、初めまして。
On 2006/09/23, at 1:13, NOBUTAKA Terauchi wrote:
> 「2.基本->do it」の最初のプログラムの"0 @
> 0"でメッセージの
> 遣り取りを調べていくと、"self basicNew"が出てきたところ
> で追い
> かけられなくなりました。
中略
> 最初は、SmallIntegerに定義されているbasicNewと思い
> ましたが、
> System Browser -> Class -> Spawn HierarchyでPointを表示
> すると
>
> Object
> Magnitude
> ArithmeticValue
> Point
>
> と表示され、上記のクラスがスーパークラスに存在しませんでした。
> ここで完全に行き詰まってしまいました。
HierarchyBrowserで"Class"のタブを選択していても、
Objectに辿り着いてしまうと
そこで打ち止めになってしまって、その先が探せなくて困りますよね。
SmalltalkのVMが、あるオブジェクトに送られたメッセージに対
応するメソッドを
見つける手順は、基本的には次の通りです。
1.そのオブジェクトのクラスのメソッド辞書中からそのメッセージを
探す
見つかれば、そのクラスで対応するメソッドが定義されている
2.見つからなければ、そのクラスのスーパークラスのメソッド辞書中
から探す。
見つからなければ、そのまたスーパークラスのメソッド辞書中から
探す。
という具合に、見つかるまで繰り返す。
3.クラス階層の頂点まで達しても(つまりスーパークラスが
nilになるクラスまで
辿り着いてしまっても)見つからなければ、そのオブジェクトは
メッセージに
答えられない。
これは、Smalltalkイディオムの"3.3 インヘリタン
ス"のメソッドサーチのくだりの
ところにも書かれています。
これをそのままSmalltalkのコードで書いてみました。
幸い、クラスのスーパークラスを求めるためのメソッドや、クラスのメ
ソッド辞書に
書かれているメッセージセレクタの集合を求めるためのメソッドがある
ので、これを
使っています。
| methodSearchBlock aBlock |
methodSearchBlock := [ :aStream :aClass :messageSelector |
aStream nextPutAll: aClass printString.
(aClass selectors includes: messageSelector)
ifTrue: [true]
ifFalse: [
aClass superclass isNil
ifTrue: [false]
ifFalse: [
aStream nextPutAll: ' -> '.
methodSearchBlock
value: aStream
value: aClass superclass
value: messageSelector]]].
aBlock := [ :anObject :messageSelector |
| aStream |
aStream := WriteStream on: String new.
(methodSearchBlock value: aStream value: anObject class value:
messageSelector)
ifTrue: [aStream contents]
ifFalse: [anObject printString, ' can not understand ',
messageSelector printString]].
aBlock value: foo value: bar
最後の行のfooをメッセージを受け取るオブジェクト(クラスでも
OK。Smalltalkでは
クラスもオブジェクトですから。)、barを送るメッセージセレ
クタに置き換えてから、
全体をセレクトしてprintItして下さい。
例1: aBlock value: 1 @ 1 value: #printString
例2: aBlock value: Point value: #basicNew
そうすると、クラス階層のどこかで見つかった場合、見つかるまでに
辿っていった
クラス階層が出力されます。
例1でやってみると、ブラウザで探すのと同じように、Objectま
で遡っていくのが
お分かり頂けると思います。
例2でやってみると、”Object class"の次が"Class"とい
うクラスになって、ブラウザ
では遡れない、さらにその先に遡っているのがお分かりいただけると思
います。
この結果から判ることは、ブラウザのクラス側で遡って行って、
Objectまで辿り着い
ても見つからなかったら、Classというクラスのインスタンス側
に移ってさらに辿って
いく、という方法を覚えておけば当面は幸せになれる、ということです
ね。
こんな風に自分でコードを書いてSmalltalkの仕組みを理解して
いけるのも、Smalltalkの
面白いところですね。
以上です。ご参考になれば幸いです。
SML メーリングリストの案内