みなさん こんにちは。
このクラスでは
Pharo を別の OOP 言語である Java と 対比します。
Pharo では オブジェクトのみを操作します。
メッセージと
変数への代入だけを行います。
これからお見せするスライドでは Java と Pharo の等価なものをいくつか見せします。
そこから違いと類似点を理解していただきます。
そこでは
Java で文字列を格納したコレクションを
つくります。
このコレクションは stringsと呼ばれる変数に代入されます。
Pharo も同じです。
コレクションを管理するクラスは
OrderedCollection と呼ばれるもので ArrayList ではありません。
しかし振る舞いは同じです。
幾つか気付くべき点を挙げます。
第1に Pharo では new はクラスに送られるメッセージです。
new メッセージが OrderedCollection クラスに送られ
そのコレクションの 新しいインスタンスが生成されます。
Java では先に new が現れます。
この構文は Java での
オブジェクト生成に特有のものです。
一方で Pharo では 標準的なメッセージ送信で行われます。
Pharo には静的型付けがありません。
Java で必要とされる多くのことが Pharo では使われません。
コレクションが格納するのが文字列であることを 指定する必要はありません。
そして strings はコレクションではありません。
もう1つ等価な式があります。 子プロセスの生成です。
このコード片を別のプロセスで
実行します。
Java では Thread クラスの新しいインスタンスを
生成する必要があります。
Runnable()を引数として与えて。
new Runnable()と書きます。
Runnable() は抽象クラスなので 未実装のメソッドを定義しなければなりません。
このメソッドは run() と呼ばれます。
そのメソッドが 子プロセスとして実行したいコードを保持します。
this.doSomething() です。
doSomething メソッドはそのコードと
同じクラスに属します。
Pharo では ずっと簡単な構文です。
同じことをするコードがこれです。
末尾の
この start で子プロセスを立ち上げます。
これを fork というメッセージを
このブロックに送ることで実行します。
Java の最新版である Java 8 からは
Java の構文がずいぶんと改善されました。
見ての通り Java のコードがずいぶん明瞭になりました。
このブロックと等価なのが
ここにあるレキシカルクロージャです。
残りは前のスライドと同じです。
Pharo では 3種類のメッセージがあります。
単項メッセージは
引数なしでレシーバーに適用されます。
前に出た factorial メソッドや
コンソールに空行を表示する
cr 等です。
二項メッセージは 1つの値を引数として
レシーバーに適用されます。
例えば 演算子です。
3と4を足す「+」のような。
-> はキーと値のペアを生成する ために使われます。
5->10 は 5 と 10 のペアを作ります。
3種類目のメッセージは キーワードです。
キーワードメッセージは1つ、2つ、3つ あるいはそれ以上の数の引数を取ります。
キーワードはコロンで区切られます。
ここにキーワードメッセージ show: があります。 Transcript オブジェクトに送られて
コンソールに表示する文字列を 引数として取ります。
2つ目の例は between:and: メッセージです。
これは2つのキーワードに分けられた 1つのメッセージです。
2つの引数を取って 1つのレシーバーに適用されます。
between:and: メッセージは オブジェクト「2」に適用されます。
そして0と5を引数として取ります。
Java と比較すると
特にキーワードメッセージについては
Java とはとても違っています。
Java では1つのレシーバーがあり、 1つのピリオドがあり
オブジェクトに送られるメッセージ の名前があり
そして括弧に囲まれてコンマで区切られた 引数があります。
Pharoでは同じことを表現するために
メソッドの名前から キーワードを区切って
引数をその中に置きます。
例えば
手紙(mail)を受取人(recipient)へ送るために
郵便屋さん(postman)に send メッセージを送ります。
これが Java の構文です。
これを徐々に分解していって 最終的に Pharo の構文にします。
1ステップ目:
Java 構文に属する部分を抽出します。
ピリオド、括弧、コンマ そしてセミコロンです。
それらを取り払いましょう。
するとこうなります。 postman send mail recipient
これを読みやすいように 1つの英文にします。
postman send mail to recipient 読みやすくなりました。
Pharo の構文として正しくなるように コロンを追加します。
メッセージは1つ。 send:to: で、postmanに適用されます。
このメッセージは引数を2つ取ります。 mail と recipient です。
if や else などの条件分岐や
do や for 等のループは
Java ではキーワードです。 Pharo ではそうではありません。
それらは言語やコンパイラが定義する 特定の単語ではありません。
それらは単にメソッドであり ある種のオブジェクトに送られるメッセージです。
Pharo では、例えば if を実行するためには
ifTrue:ifFalse: メッセージを送ります。
これは1つの真偽値(Boolean)に 送られるメッセージです。
2つのブロックを引数として取ります。 1つはもし真偽値がtrueの時に実行されて
もう1つは真偽値がfalseの時に実行されます。
同様に、ループは単にある種のオブジェクトに 送られるメソッドに過ぎません。
1つ目の例では
4 は数値オブジェクトです。
timesRepeat:メッセージを ブロックを引数として送ることができます。
対応するメソッドがブロックを
レシーバが表す通りの回数だけ実行します。
4 timesRepeat: は 何かを4回実行します。
同様に、to:do: は 数に送られるメッセージです。
1つの数と1つのブロックを 引数として取ります。
ブロックの引数である i は
0から100までの各値を取ります。
同様に
to:by:do: メッセージは
0から100までの3の倍数を
値として選びます。 0、3、6、9、等。
最後に do: はコレクションに送られるメッセージで
Java の foreachループと同じです。
do: メッセージはコレクションの 各要素についてブロックを実行します。
変数 each は
最初にコレクションの
1番目の値を取ります。
ブロックが このeachの値を使って実行されて
それから each は コレクションの2番目の要素を取ります。
この値でブロックが実行されて コレクションの最後まで繰り返されます。
まとめると 3種類のメッセージがあります。
単項メッセージ、二項メッセージ そしてキーワードメッセージ。
優先順位は
最初に括弧の中が実行されます。
そして単項メッセージ そして二項メッセージ、そしてキーワード。
条件分岐やループは
ある種のオブジェクトへのメッセージです。
Java 等の他の言語では
それらは言語の特殊なキーワードで
コンパイラへの特定の指示ですが
Pharo では、それらは 特定のオブジェクトへのメッセージです。