第60回
■
■SqueakではじめるSmalltalk入門 第60回
■
本連載では、名前は知っていてもなかなか触れる機会のないSmalltalkについて、最近話題のSqueakシステムを使って紹介しています。前回は少々寄り道をして、ジョブズやアトキンソンたちが1979年のPARC見学の際にかいま見たであろう、ALTO/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
ワークスペースなど適当な場所にこのスクリプトを貼り付けて、全体を選択してからdo it(cmd + D)するとメニューを呼び出せます。前々回はこのメニューをモーフとして選択しインスペクト(検査)しました。今回は、メニューを構成するメニュー項目の中味をインスペクトしてみることにします。
スクリプトの記述からも伺えるように、そして、#add:action:、#add:target:selector:などのメソッドをシステムブラウザを使って“上流”に遡ることで#addMorphBack:メソッドの起動を確認できることからも、メニュー項目モーフ(a MenuItemMorph)がメニューモーフ(a MenuMorph)のサブモーフとして登録されていることは、すでにご説明したとおりです。
あるモーフに登録されたサブモーフをインスペクトするためには、コマンドクリックを繰り返す方法をすでに紹介済みですが、今回は、インスペクタの新たな操作法のレクチャーを兼ねて、サブモーフ群がオーナーのsubmorphsというインスタンス変数に束縛されていることを利用することにします。
まず、オーナーモーフであるメニューをコマンドクリックでモーフとして選択。現れたハローのうち右手上から二番目のグレイのハロー(デバッグハロー)をshiftキーを押しながらクリックすると、そのメニューのインスペクタを開くことができます。この操作はすでにお馴染みですね。
では次に、開いたインスペクタで、左手のリストペインのsubmorphsをダブルクリックしてみてください。するとsubmorphsに束縛されている配列(anArray)のインスペクタが現れます。Smalltalkシステムでは、このようにインスペクタを介して、オブジェクトのネットワークの海の深みに向かって次々に“ダイブ”してゆくことが可能となっています。
[fig.A]submorphsのダブルクリックで現れた新しいインスペクタ
さて。我々が興味を持つサブモーフとしてのメニュー項目は、今、インスペクト中の配列の要素として束縛されています。メニュー項目は五つなのに、この配列には七つの要素があることを不思議に思ったかたは、メニュー項目だけではなく、区切り線もモーフ(a MenuLineMorph)であり、サブモーフとして登録されていることを思い出してください。
区切り線の二番目と六番目以外はメニュー項目なので、どれを選んでもかまわないのですが、ここでは最後の要素、つまり、選択するとワークスペースを開くメニュー項目を観察することにしましょう。
インデックス「7」の要素をダブルクリックして改めてインスペクタを開いてみてください。このとき、すでに項目が選択されているとダブルクリックしてもうまくインスペクタが開かないことがあります。いったんクリックして選択を解除してから改めてダブルクリックするか、ダブルクリック操作ではなくinspect it(cmd + I)をタイプしてください。インスペクタが開いたら、内容を見やすくするために、右下付近にポインタを合わせ、すこしウインドウサイズを大きめにしましょう。
[fig.B]配列のインスペクタから呼び出したメニュー項目のインスペクタ
左手のリストペインに、メニュー項目モーフに用意されたインスタンス変数が列挙されています。最後のほうにあるtarget、selector、argumentsに注目してください。これらには、前述のスクリプトでこのメニュー項目を追加するときに指定した、ターゲットであるWorkspace、セレクタである#openLabel:、メッセージ送信に際して必要になるパラメータ(引数)として、'My NewWorkspace'を要素に持つ配列がそれぞれ束縛されているはずです。
メニュー項目は自らが選択されると、指定されたターゲットに、セレクタとパラメータを組み合わせたメッセージ(このメニュー項目では、「openLabel:'My New Workspace'」というメッセージ)を送信することで、その役割を果たします。試しに、このインスペクタで別のターゲットにすげ替えて、メニュー項目を選んだときにどんな挙動を示すかを観察してみましょう。
インスペクタの左手リストペインからtargetを選択します。右手のペインには今は束縛されているWorkspaceが表示されます。これを「Transcript」と書き換えてaccept(cmd + S)します。すると、ペインの内容は「aTranscriptStream ''」と変わります。これで、メッセージの送り先をクラスWorkspaceからトランスクリプト(TranscriptStreamのインスタンス。グローバル変数のTranscriptに束縛されている…)への、すげ替えが完了です。トランスクリプトも「openLabel: aLabelString」というメッセージを受けることができるので、問題はありません。
では、おおもとのメニューに戻って「open workspace」を選択してみてください。もし、何らかの理由でメニューがすでに消えてしまっていたら、最初に開いたメニューのインスペクタで「self openInWorld」をdo it(cmd + D)することで再び呼び出すことができます。
さて。メニュー項目を選択後に開いたウインドウは、一見、ワークスペースのように見えますが、さにあらず。これはれっきとしたトランスクリプト(標準出力もどき)ウインドウです。その証拠に、どこか適当な場所、たとえば、インスペクタの下部にあるペインで、
Transcript show: 'Hello World'
とタイプしてからdo it(cmd + D)すると、「Hello World」ときちんと表示されるはずです。
このページを編集 (5378 bytes)
|
以下の 1 ページから参照されています。 |
This page has been visited 698 times.