vieweditattachhistorytopchangessearchhelp

第05回


■SqueakではじめるSmalltalk入門   第5回


 本連載では、名前はよく耳にしていてもなかなか触れる機会のないSmalltalkについて、最近話題のSqueakシステムを使って紹介しています。今回は前回提示した短いペイントスクリプトの内容に順を追って解説を加えます。

 前回のプログラムは次のようなものでした。便宜的に、行頭にはコメントのかたちで行番号を振ってあります。

"01" | pen |
"02" pen _ Pen new.
"03" pen defaultNib: 3.
"04" pen color: Color red.
"05" [Sensor shiftPressed] whileFalse: [
"06"    | position |
"07"    position _ Sensor peekPosition.
"08"    Sensor redButtonPressed
"09"       ifTrue: [pen goto: position]
"10"       ifFalse: [pen place: position]]


 Smalltalkのプログラムコードは、目が慣れてしまえば、自然言語(英語)の文章を読むように、比較的容易にその内容を理解できるのがその特徴です。もちろん、変数名やメソッド名(セレクタ)を考える際に、それを使って書いたコードが、平易で読み下し易いものになるよう心がけることが推奨されており、ユーザー(プログラマ)がそれを遵守することが前提です。結果、変数名やメソッド名は長くなりがちですが、組み込みエディタの簡易補完やコンパイラのスペル修正機能のサポートが期待できるので、初期のProject Builderにおける、Objective-C/CocoaプログラミングやAppleScriptプログラミングのときのようなストレスを心配する必要はないでしょう。

 1行目は、一時変数「pen」の宣言です。ちなみに、複数の一時変数を宣言したいときは、スペースで区切って列挙します。FORTRANやALGOLの流れを汲む言語でよく見られる「,」(コンマ)を区切り記号に使わないのは、Smalltalkが前二者よりLISPからの影響を強く受けているからだと思います。余談ですが、コンマは「コレクション」と呼ばれる配列の仲間(文字列を含む)のオブジェクト同士を連結するときに用いる二項セレクタ(関数名)として登録されているので、項目列挙の際に区切りのつもりでうっかり使うとエラーになったり、思わぬ結果が生じることもあるので気を付けてください。

#(1 2 3 4), #(5 6 7)   "=> #(1 2 3 4 5 6 7) 配列の結合 "
'This is a ', 'pen.'   "=> 'This is a pen.' 文字列の結合 "


 話を戻して、2行目は宣言した一時変数「pen」に、クラス「Pen」のインスタンスを束縛(代入)しています。Smalltalkの変数は型を持たないため、中にデータを入れる“箱”というよりは、本来無名のオブジェクトに付ける“名前”になぞらえたほうがしっくりきます。また、ここで「代入」や「命名」ではなく「束縛」という言い回しをするのは、変数への束縛が、単に名前を付けるというだけでなく、オブジェクトの寿命を決定づける意味合いも持つからです。仮に「Pen new」を評価してオブジェクトを生じさせても、そのまま放っておけばガベージコレクタに瞬殺されてしまいます。誕生させたオブジェクトを確保し、続く式でメッセージを送って何らかの振る舞いをさせるための参照と延命のための作業が、変数への“束縛”、というわけです。

 前後しますが「Pen new」は、クラス「Pen」にメッセージ「new」を送信してオブジェクトを生成するための式です。クラスはオブジェクトの設計図と言うべき存在で、そのクラスに属するオブジェクト(インスタンス)が内部にいくつのメモリ(インスタンス変数)を持ち、どんなメッセージに応答でき(セレクタ)そのときどんな振る舞いをするか(メソッド)を定義します。システムは、クラスの定義記述に従ってオブジェクトを生みだし、しかるべく振る舞わせます。

 Smalltalkでは、クラスもまたオブジェクト(クラスのクラスの唯一のインスタンス)なので、メッセージを受けることができ、それに相応しい決められた振る舞いをします。メッセージ「new」は、そのクラスに属するインスタンス(オブジェクト)を生成するために送る一般的なメッセージです。クラス「Pen」は有名な、しかしSmalltalkが発祥だとは意外と知られていない「BitBlt」(bit block transfer)クラスのサブクラスで、LOGOの“タートル”のような振る舞いをするオブジェクトを定義します。

 二つ以上の式を区切って区別するには「.」(ピリオド)を用います。これは終端記号ではないので、最終行には付ける必要はありません(あってもエラーにはなりません)。改行や余計なスペース、タブは式の解釈には影響を与えないので、主に可読性向上を目指した整形のために用います。

 3行目と4行目では一時変数「pen」に束縛した、Penのインスタンスに対してメッセージを送ることで、その“状態”を変化させています。3行目で送っているメッセージ「defautlNib: 3」はペン先(nib)の太さを3ドットに変更するためのもので、4行目の「color: Color red」はペンの色を赤に変えるためのものです。念のためおさらいしておくと、前者のセレクタは「#defaultNib:」パラメータは「3」、後者のセレクタは「#color:」パラメータは式「Color red」の返値となります。式「Color red」自体もメッセージ式で、クラス「Color」に「red」というメッセージを送りColorに属する“赤い色”というオブジェクトを生じさせています。同様に、「Color blue」とすれば“青い色”、「Color green」とすれば“緑色”を指定できます。

 これでペン「pen」の準備ができたので、あとはマウスの動きにpenの動きを、マウスボタン操作にpenの上げ下げ連動させればお手軽ペイントソフトを機能させることができます。この部分を記述したのが5行目以降です。

 次回は、ループやif-then-elseといった条件分岐を、通常のプログラミング言語がするような「構文」ではなく、どのようにして「式」で表現しているのかを解説します。

このページを編集 (4836 bytes)


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

This page has been visited 1333 times.