







第58回
■
■SqueakではじめるSmalltalk入門 第58回
■
本連載では、名前は知っていてもなかなか触れる機会のないSmalltalkについて、最近話題のSqueakシステムを使って紹介しています。前回に引き続き、簡単なスクリプトで作成したポップアップメニューの機能を果たすモーフを用いて、これをSmalltalkならではのツールを用いて解析し、その仕組みをより細部にわたって観察してみましょう。
念のため、スクリプトを再掲します。
| menu |
menu := MenuMorph new.
menu defaultTarget: 1.
menu add: 'default (one)' action: #inspect.
menu addLine.
menu add: 'two' target: 2 selector: #inspect.
menu add: 'three' target: 3 selector: #inspect.
menu add: 'four' target: 4 selector: #inspect.
menu addLine.
menu
add: 'open workspace'
target: Workspace
selector: #openLabel:
argument: 'My New Workspace'.
menu invokeModal
CocoaのApplication Kitでメニューを作る手続きととてもよく似ていますね。このスクリプトをワークスペースなどにペーストした後、全体を選択してdo it(cmd + D)することで、次図のようなポップアップメニューを機能させることができます。
[fig.A]スクリプトで作られたポップアップメニュー

こうして作られたメニューも他のGUIウィジェット同様にモーフで構成され、主にコマンドキーを用いたモーフとしての操作も受け付けます。たとえば、コマンドクリック(コマンドキーを押しながらクリック)でモーフとして選択したり、そのままドラッグして移動させることができます。
[fig.B]モーフとして選択されたポップアップメニュー

ハローのうち、右端の上から2番目にあるグレイのボタンは「デバッグハロー」と呼ばれ、クリックすると、選択しているモーフに関する「デバッグメニュー」をポップアップします。デバッグメニューには、選択したモーフの内部的な情報にアクセスするのに便利なメニュー項目が用意されています。
[fig.C]デバッグハローとデバッグメニュー

このうち「モーフの検査」というメニュー項目を選択することで、選択したモーフ(今の場合、自作のポップアップメニュー)のインスペクタを開くことができます。
すべてのモーフはsubmorphsというインスタンス変数を持ち、これに自分に属するサブモーフを束縛しています。今開いたインスペクタの左上のリストペインでsubmorphsという欄をクリックすると、先のスクリプトで#add:action:などを介して定義したメニュー項目モーフ(a MenuItemMorph)がその数だけ登録されていることを確認できます。
[fig.D]自作ポップアップメニューのsubmorphs

また、ownerというインスタンス変数には、逆に自分がサブモーフとして属しているモーフが束縛されています。今はnilになっていますが、これはデバッグメニューを開いたときに観察対象のメニューモーフが画面から消えてしまっているからです。デバッグハローをshiftキーを押しながらクリックすることで、メニューを介さずに直接インスペクタを開くショートカットを使えば、観察したいメニューを消さずにインスペクタを同時に開くことが出来るので、この方法で再度ownerを見てみましょう。
[fig.E]ポップアップメニューのownerの確認

すると先ほどのnilの代わりに本来のa PasteUpMorph(n) [world](nは適当な数値)が束縛されていることが分かります。PasteUpMorphとは、デスクトップを表現するのに用いられているモーフの属するクラスです。また、ここでnはオブジェクトにhashというメッセージを送ったときに得られるオブジェクト固有の数値(原則として…)で、オブジェクトの同等性の判断に使われます。
では引き続き、デスクトップをコマンドクリックしてモーフとして選択した後、右側に現れたデバッグハローをshiftクリックすることで、デスクトップのインスペクタを呼び出してみてください。インスペクタとのタイトルバー、あるいはselfを選択して右側のペインに表示される内容と、先ほどのポップアップメニューのownerの値は一致しているはずです。
つまり、ポップアップメニューは、メニュー項目をサブモーフとして追加して組み立てられたあと、デスクトップにサブモーフとして追加されることで、我々の前に現れたわけです。非常にシンプルで、わかりやすい動作モデルですね。
実装からも同様のことを確認することが可能です。スクリプト中のinvokeModalを選択してbrowse it(cmd + B)でブラウザを開き「implementors」ボタンを使って、#invokeModal: →#invokeModalAt:in:allowKeyboard: → #popUpAt:forHand:in:allowKeyboard:とたどってゆくと、そこでデスクトップを束縛したaWorldに対してメッセージ「addMorphFront: self」を送信していることがわかります。
このページを編集 (4020 bytes)
 |
以下の 1 ページから参照されています。 |
This page has been visited 809 times.