第11回
■
■SqueakではじめるSmalltalk入門 第11回
■
本連載では、名前は知っていてもなかなか触れる機会のないSmalltalkについて、最近話題のSqueakシステムを使って紹介しています。今回は、前回起動したシステムブラウザでクラスに定義されたメソッドのブラウズを行ないます。
システムブラウザは、上段4つ下段ひとつの計5つのペインから構成されています。
[fig.A]Stringをブラウズする準備が整ったシステムブラウザ
慣れるまでの当面のあいだ、とりあえず注目しておけばよいペインは、上段の左から偶数番目(2番目と4番目)のペインと下段のペインです。上段左から2番目のペインは、ご覧いただいているように、ブラウズしているクラス、そのものズバリです。4番目のペインにはそのクラスのインスタンスが応答できるメッセージに使用できるセレクタ、すなわちメソッド名が列挙されています。この4番目のペインの項目をクリックすると、下のペインに選択したメソッドのコードが表示されます。
たとえば、4番目のペインを一番下までスクロールして「withCRs」を探してクリックして選択してみてください。すると下のペイン(コードペインとも言う)にはメソッド「String >> #withCRs」のソースコードが現われます。
[fig.B]String >> #withCRsのソースコードを呼び出したところ
Squeakシステムにはリファレンスマニュアルのようなものは用意されていません。知りたいことは、原則としてすべて、このシステムブラウザを通じて入手することになります。事実、私たちは今、StringのインスタンスがwithCRsというメッセージを受け取ることができること、また、StringのインスタンスはwithCRsというメッセージを受けることによって、自身に含まれるバックスラッシュ(\。メールでは¥と表示されます)を改行文字に置き換えるメソッドを起動すること、そのメソッドはどのように実装されているか、を目前のブラウザから得ることができます。実際に文字列オブジェクト(Stringのインスタンス。a String)にメッセージ「withCRs」を送信し、その振る舞いを確認してみましょう。
'Smalltalk-80\Squeak\VisualWorks' withCRs
" => Smalltalk-80
Squeak
VisualWorks "
print it (cmd+P)すると、先にブラウザから得た情報通り、自身の$\を改行に置き換えた文字列を返してきます。余談ですが、このメソッドはポップアップメニューを作るときによく使われます。
(CustomMenu labels: 'Smalltalk-80\Squeak\VisualWorks' withCRs) startUp
Smalltalkでは文字列リテラルに改行を含むことができるので、上のコードは次のものと同じです。メニュー項目が数個なら、#withCRsを使うことで、コードの見栄えが多少良くなる、という程度の効果はありそうですね。
(CustomMenu labels: 'Smalltalk-80
Squeak
VisualWorks' withCRs) startUp
さて話を戻しましょう。String >> #withCRsのソースコード中で、selfはこのメソッドを起動したオブジェクト(メッセージの受け手。レシーバ)を束縛する偽変数(代入できない変数)、#ifTrue:ifFalse:はすでにご存じのとおり条件分岐をメッセージ送信で行なうためのもの、Character crはクラスCharacterにcrを送信しておそらく改行文字を返値として得ていると予想できると想定して、残りのcollect: [:c | ...]というメッセージ送信により何を期待しているかだけが分からなかったと仮定しましょう。これをブラウザに備え付けのサービスを使って調べるには次のような手順を踏みます。
ブラウザ上下段のペインに挟まれるように並んでいるボタン群のうち「implementors」とラベルされたボタンをクリックします。すると、このメソッドのセレクタと、メソッドのソースコードの中で送信されているメッセージに用いられているセレクタをすべて含んだメニューがポップアップするので、その中から「collect:」を選びます。すると、#collect:を定義しているクラスとその実装を呼び出すための一覧を含んだウインドウが現われます。話を簡単にするため、ここでは上段のペインに示されたリストから「SequenceableCollection collect: {enumerating}」をクリックして選択してみてください。
[fig.C]SequenceableCollection >> #collect:のソースコード
実はStringのインスタンスは、メッセージ「collect: aBlock」を受けて、このSequenceableCollection >> #collect:を起動します(この仕組みは、スーパークラス/サブクラスへの言及のときに説明します)。このメソッドのコメント、あるいはコードから、各要素(文字列の場合は先頭からの各文字)を、aBlockとして与えられたブロック(無名関数)を評価した結果の返値で置き換えた新しい文字列を返すメソッドであることを読みとることができるでしょう。こうして、元のString >> #withCRsに戻って、レシーバである文字列を頭からスキャンし、$\なら改行文字に、それ以外はその文字のまま置き換えた新しい文字列を返す作業をしていることが理解できる…というわけです。
かなり乱暴な説明でしたが、Squeakシステムでは「すべての情報をシステムブラウザを通じて入手する」ということが意味するところと、リファレンスマニュアルが用意されていない理由がちょっとだけお分かりいただけたと思います。さらにここで注意したいのは、Smalltalkにおいてはメソッドもまたオブジェクトであり、そのソースコード、コード中で送信されるメッセージに用いられるセレクタの一覧などの情報も、メソッド“本人”に問い合わせることで入手可能だということです。つまり、豊富で便利なサービスを提供しているかのように見えるブラウザはあくまで、クラスやメソッドといったオブジェクト達が本来持ち合わせている能力を引き出すためにGUIを提供する仲介者に過ぎないのです。実際、メソッドにメッセージ送ることで、今、得られたような情報は簡単に入手できます。
(String >> #withCRs) messages
" => 使用されているセレクタ一覧 "
(String >> #withCRs) getSourceFromFile
" => メソッドのソースコード "
次回は、メソッドやクラスを整理するための「カテゴリ」についてです。
補足:
Squeakを含むSmalltalkシステムでは一般に、“$”は文字(a Character。文字列やシンボルの要素)の、“#”はシンボル(a Symbol。等価なら同一性が保証される特殊な文字列)のリテラル式の先頭に用いられます。
これを模して通常の文章でも、いちいち「文字列(Character)クラスのインスタンスの“\”」など書きたくないときに、それと等価なオブジェクトを生成するリテラル表記「$\」をそれに代えて用いることがよくあるので慣れておいてください。ちなみに、セレクタを#ifTrue:ifFalse:のように表記するのは、その実体がシンボルであることに由来します。
また“#”は、シンボルリテラルとは別に「#('this' #is $a 10)」というふうに、要素(ただしリテラルに限る)をスペースで区切って列挙し括弧で括ったものの先頭に付すことで、指定した要素を持つ配列の生成するときにも使用します。
このページを編集 (5931 bytes)
|
以下の 1 ページから参照されています。 |
This page has been visited 1084 times.