[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 メーリングリストの案内