「Smalltalkを使ってみる」
さて、ここでは「SqueakはSmalltalkである」ということで、Squeakを使ってSmalltalkという言語を使ってみることにします。Squeakでは、今までSqueak・トーイと呼ばれる部品にパネルを使ってスクリプトを書いてきました。が、これは「Smalltalkのプログラム」ではありません。これはSqueakのために構築された環境であり、Smalltalkとは直接関係ないものなのです。
では、Smalltalkのプログラムというのはどんなものか。一番簡単にそれを見られるのは、「ボタン」のスクリプトでしょう。——とりあえず、デスクトップに「ボタン」を1つ配置して下さい。そしてハロを表示し、下辺のやや右辺りにある淡いグリーンのハロをクリックします。すると、スクリプトを表示するパネルが現れます。
が、なんか今までのスクリプト・パネルとは様子が違いますね。「self」なんて、いかにもプログラミング言語の予約後っぽいものが書かれています。そう、これはパネル・スクリプトで実行される「生のSmalltalkプログラム」が見えているのです。
実はこれ、普通のスクリプト・パネルでも簡単に見られます。「!」マークの隣の◎マークの更に隣にある四角いマークをクリックしてみましょう。上の表示が、ごく普通のスクリプト・パネルの表示に戻っちゃいます。このマークをクリックすることで、「パネルのスクリプト」と「Smalltalkのプログラム」を切り替え表示できるようになっていたのです。
これを使えば、Smalltalkのプログラムがどんなものか、とりあえず覗いてみることはできます。とりあえず、適当に部品を操作するパネルを入れて、切り替え表示してみましょう。どんなことが裏側で実行されているのか見えて、なかなか面白いですよ。
例えば、これは楕円を使ってペンをいろいろ操作してみたスクリプトです。何やら「self ○○」といった文がずらっと並んでますね。こんな具合にして、Smalltalkのプログラムが作成されていたんですね。
とりあえず、簡単なプログラムを書いて動かすのに必要な最小限の知識はこんなところでしょうか。これでも、重要な要素をかなりざっくり削ってあるんですけど、まあ最初から何でも暗記できるわけはないので、こんなところで十分でしょう。1.Smalltalkはオブジェクト指向言語である。
最近、よく耳にしますね。「オブジェクト指向」って。要するにオブジェクトとかいう代物の形でプログラムができてるってやつですね。このオブジェクト指向、実はSmalltalkによって誕生した、といってもいいようなもんです(・・ほんとはそうでもないけど、ま、広めたのはSmalltalkの力っていっていいかも)。最初から「すべてをオブジェクトとして扱う」ということを考えて作られたのがSmalltalkなのです。
2.Smalltalkでは、すべてのものはオブジェクトである。
Smalltalkという言語では、すべてのものは「オブジェクト」として扱われます。オブジェクトっていうのは何か? これは、「それ自身の中に、それを扱うのに必要な全てが入っているもの」という感じのものです。例えば、普通の変数とかそういうのだと一つの値しか扱えないですね。そうじゃなくて、必要な値も、それを操作する機能も、すべて1つにまとまっている、って感じのものです。
3.オブジェクトは、クラスから作られる。
Smalltalkでは、プログラムで扱われる様々な要素は「クラス」と呼ばれる形で定義されます。これは、一種の設計図みたいなものです。このクラスを元に「インスタンス」と呼ばれるオブジェクトが作られ、それを使っていろいろプログラムを動かしたりするわけです。例えば、ボタンを作って使いたいと思えば、ボタンのクラスからインスタンスを作り、そのインスタンスの中の機能を呼び出したりして操作する、というわけです。
4.クラスの中には変数と「メソッド」がある。
クラスは、その中に必要な値や機能がまとめられています。値は変数としておさめてありますし、機能は「メソッド」と呼ばれる小さなプログラムとして入ってます。ある機能を利用したければ、そのオブジェクトに向けて「このメソッドを呼び出して下さい」というようにお願いするわけです。
5.メソッドの呼び出しは、「メッセージ」を送って行う。
では、メソッドの呼び出しはどうやって実行するか? それは、「メッセージ」と呼ばれるもので行ないます。あるオブジェクトにメッセージを送ると、そのメッセージに対応するメソッドが呼び出され実行される、というようになっているわけです。——Smalltalkという環境は、無数のオブジェクト間でさまざまなメッセージを送りあいながら動いている、と考えて良いでしょう。
6.メッセージは、オブジェクトの後にセレクタやキーワードが続いた形をしている。
メッセージは、受け取るオブジェクト(レシーバといいます)の後に、メッセージの種類を識別する様々な要素を記述します。これは大別して「単項/二項式」と「キーワード式」というものになります。キーワードとかセレクタとかなんか難しそうですが、要するに「普通の言語の命令とかに相当するものなんだ」と考えておけば今は十分です。
・単項式: レシーバ セレクタ
(例) 90 sin (90というオブジェクトにsinというメッセージを送る)
・二項式: レシーバ セレクタ 引数
(例) 5 + 7 (5というオブジェクトに+ 7というメッセージを送る)
・キーワード式: レシーバ キーワード:引数
(例) myobject go:100 (myobjectというオブジェクトにgo:100メッセージを送る)
7.制御構文に相当するものでは、[]を使ってまとめる。
繰り返しや条件分岐に相当する文などでは、[]という記号を使い、その中に実行するメッセージを書くことがあります。この[]でくくったものは「ブロック」と呼ばれます。これは遅延評価とかいう難しそうなことをするもんですが、まぁ後で構文(?)を使うようになったら覚えればいいでしょう。今は「そういうもんがある」ってことで。
8.各文は、ピリオドで区切って書く。
ある程度のプログラムともなればいくつもの文を続けて書くことになりますが、こうした場合、文と文の間にピリオドを入れて、「ここが文の切れ目です」ということを示さないといけません。ピリオドを入れておけば、改行などしなくとも別の文と認識します。が、入れないと、たとえ改行してあっても「ここで文が切れている」と認識してくれないので注意して下さい。
9.Smalltalkでは、大文字と小文字は「別の文字」。
これも最初に覚えておきましょう。Smalltalkでは、大文字と小文字は別の文字です。「a」と「A」は違うものだし、「true」と「True」も別のものになります。これは、けっこう引っかかることが多いので忘れないように!
10.「A」と「A:」は「別のもの」。
これもよく引っかかります。SmalltalkではAというように一つの単語のものと、「A:」というように後ろに:記号がついたものがよく出てきますが、これらは全く違うものです。うっかり:をつけ忘れたりすると動かないので注意!
|a b| |
1.変数は、最初に||記号の間に書いておく。実行ブロックの部分は、前にいった[]記号の中に実行するメッセージを順番に書いておけばいいわけですね。それから真義値のオブジェクトってのは、「真義値の値が得られるもの」と考えておけばいいでしょう。例えばさっきの例のように「○○=××」というようなものがくるわけです。
Smalltalkでは、変数は最初に|a|というようにして|記号で挟んで書いておきます。もし複数必要ならば、それらは半角スペースを空けて続けて書きます。
2.Smalltalkでは、変数には「型」がない(?)。
見ればわかりますが、Smalltalkの変数は「どんな値を入れるものか」という型(タイプ)の指定がありません(ってゆーか全部「オブジェクト型」なんで、まぁ「ない」って思っていいかも)。内部的には値に型はありますが、変数を使う際にそれらを指定することはありません。
3.数字はそのまま。テキストはシングルクオートで。
Smalltalkで数字を扱うときは、そのまま数字を書けばいいです。またテキストの場合は、前後をシングルクォートでくくり、'Abc' というように書きます。
4.四則演算用の二項式はいろいろある。
四則演算に相当する二項式のセレクタは「+」「−」「*」「/」「//」「\\」といったものがあります。最初の4つはわかりますね? それぞれ加算・減算・乗算・除算のものです。その後は、わり算の整数値を得るものと、余りを得るものです。とりあえずこれらは計算の基本なので覚えておきましょう。
5.条件分岐は、ない。けど相当するメッセージはある。
前に触れたように、Smalltalkは予約語を記述してあれこれするもんじゃありません。従って、条件分岐なんて構文もありません。じゃあどうするかというと、「オブジェクトがtrueのときに引数のオブジェクトを評価するメッセージ」「オブジェクトがfalseのときに引数を評価するメッセージ」というものがあるのですよ。それが「ifTrue:」「ifFalse:」というキーワード式です。
6.ifTrue: と ifFalse: の式の書き方を覚えておこう!
では、この条件分岐のように機能するキーワード式の書き方を覚えておきましょう。これは、以下のよう中たちで記述します。ifTrue/ifFalse単体でも使えますし、両者が逆になっていても受け付けてくれます。
真偽値のオブジェクト ifTrue: 実行ブロック ifFalse: 実行ブロック