







第59回
■
■SqueakではじめるSmalltalk入門 第59回
■
本連載では、名前は知っていてもなかなか触れる機会のないSmalltalkについて、最近話題のSqueakシステムを使って紹介しています。
前回は、メニューがポップアップするときに起動されるメソッドを“上流”にたどることで、ポップアップメニューにメニュー項目がサブモーフとして登録されるのと同じように、ポップアップメニュー自身もデスクトップにサブモーフとして登録される…という統一的な動作モデルで画面表示が構成されていることを確認しました。なお、システムには他に同名のメソッドがないので「popUpAt:forHand:in:allowKeyboard:」を(タイプ、あるいはコピー&ペーストして入力後…)選択してからcmd + B(browse it)すれば、再び前回と同じ操作を繰り返すことなしに、当該メソッドのソースコードを一発で再び呼び出せます。
ところで、このメソッド#popUpAt:forHand:in:allowKeyboard:には、前回の内容に絡めてちょっと面白い情報も一緒に含まれています。1回分まるまる使ってしまう少々長めの余談となりますが、立ち寄りついでにそれをご紹介することにいたしましょう。
前回、ポップアップメニューのデバッグハローを単にクリックして(つまりshiftキーを押さずに…)デバッグハローメニューを呼び出してしまうと、解析したいポップアップメニューが消えてしまったのを覚えておられるでしょうか。そこで、デバッグハローから直接、インスペクタをよびだすためにshift-クリックを使用したのでしたよね。
[fig.A]デバッグハローメニューを出すと、元のメニューが消えてしまう

これはメニューモーフ独特の挙動で、他のモーフはこんなことはありません。で、どうしてこんなことが起こるのかの答えが、実は今、ブラウズしていただいている#popUpAt:forHand:in:allowKeyboard:に書かれているのです。
このメソッドの最初の部分がそれです。
aWorld submorphs
select: [:each |
(each isKindOf: MenuMorph) and: [each stayUp not]]
thenCollect: [:menu | menu delete]
- select:#thenCollectという見慣れないメソッドを使っているので、すでに皆さんがご存じの#select:、#collect:に置き換えて、同じことをするコードに書き直してみます(#select:、#collectについは、第34回を参照)。と、申しましても、単に前半を括弧でくくって、thenCollect:以降を#collect:を起動する独立したメッセージにするだけです。
(aWorld submorphs
select: [:each |
(each isKindOf: MenuMorph) and: [each stayUp not]])
collect: [:menu | menu delete]
ちなみに「select:thenCollect:」を入力して選択後、browse it(cmd +B)して見ることができる定義にも、実は同じことが書いてあります。単に括弧をひとつ省くためだけのメソッドの存在をいぶかしがる向きもあるかと思いますが、かのマーチン・ファウラーはこうした冗長さを称して“ヒューメイン(人道的)”な言語デザインなのだと言っています。
http://capsctrl.que.jp/kdmsnr/wiki/bliki/?HumaneInterface
さらに踏み込んで、このコードに限っては、次のように書いても同じことになります。
(aWorld submorphs
select: [:each |
(each isKindOf: MenuMorph) and: [each stayUp not]])
do: [:menu | menu delete]
本来、#select:thenCollect:は、その定義どおり、#select:(パラメータブロックがtrueを返す要素を選別)したコレクションに対して#collect:(パラメータブロックの返値を改めて要素としたコレクションを新たに作成)するときに用いるメソッドなのですが、ここでは返値を捨てている(変数に束縛していない)ので、#do:(各要素についてパラメータブロックを評価)しているのと同じ…というわけです。
察しのよい読者の皆様におかれましては、#select:thenCollect:の説明など見るまでもなく、このコードがデスクトップ(aWorld)に存在するメニューモーフを一掃するためのものであることをご推察いただけていることと思います。試しにこのコードをコメントアウトして、どうなるか確認してみましょう。コメントアウトするには、このコードの前後にダブルクオーテーション「"」を追加して、accept(cmd + S)します。
ただちにコンパイルが終了し、システムはコメントアウトしたコード抜きで新たな挙動を示すようになります。改めて前々回のスクリプトでポップアップメニューを出してモーフとして選択後、デバッグハローメニューを呼び出してみてください。いかがですか? もう、元のメニューは消えませんよね。
[fig.B]デバッグハローメニューを出しても、消えなくなったメニュー

こんなふうに、システムの仕組みや動きがどんなふうになっているかを気軽に、かつ、安全に学べるようになっていることも、アラン・ケイが考えるダイナブックの備えるべき(そして、Mac のような“限定”ダイナブックでは削られて久しい…)特徴のひとつであり、暫定ダイナブックシステムとしてのSmalltalkは見事にそれを体現しているわけです。
今回、手を加えたメソッドは、ブラウザのversionボタンで呼び出すことができるバージョンブラウザから一つ前のバージョンを選択して、revert、remove from changesの順にボタンを押して明示的に戻すか、システムを保存せずに終了して再起動することで変更自体をなかったことにできます(後者の場合は、起動後加えた他の変更もすべて失われるので注意してください)。
このページを編集 (4583 bytes)
 |
以下の 1 ページから参照されています。 |
This page has been visited 756 times.