vieweditattachhistorytopchangessearchhelp

第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]スクリプトで作られたポップアップメニュー
Uploaded Image: 58a.png

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

[fig.B]モーフとして選択されたポップアップメニュー
Uploaded Image: 58b.png

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

[fig.C]デバッグハローとデバッグメニュー
Uploaded Image: 58c.png

このうち「モーフの検査」というメニュー項目を選択することで、選択したモーフ(今の場合、自作のポップアップメニュー)のインスペクタを開くことができます。

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

[fig.D]自作ポップアップメニューのsubmorphs
Uploaded Image: 58d.png

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

[fig.E]ポップアップメニューのownerの確認
Uploaded Image: 58e.png

すると先ほどの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)


Congratulations! 以下の 1 ページから参照されています。

This page has been visited 800 times.