はじめてのMorphicチュートリアル(第3回)「モーフの位置」

第2回ではモーフの大きさの取得や設定の方法について学んだ。今回はモーフの位置などを取得・設定する方法について学ぶ。
モーフの位置の取得・設定はさまざまな手段が用意されている。まずモーフの四隅の座標値は以下のメッセージで取得することができる。

topLeft
左上の座標
topRight
右上の座標
bottomLeft
左下の座標
bottomRight
右下の座標

前回の例と同様、上のメッセージにコロン(:)をつけて座標値とともにキーワードメッセージを送ると、それぞれの値を設定することができる。当然のことながら、どのやり方で座標値を設定してもモーフの位置が変化するだけで大きさが変わるわけではない。
取得と設定の応用として、二つを組み合わせた例を以下に示す。これをPlaygroundの右下のペインに入力し、Command-D(Alt-D)で評価してみよう。

self topLeft: (self topLeft + (2@0))

モーフが少し右に移動したのがわかるだろうか。
この式の意味は、まずself topLeftによってモーフの左上の座標値を得る。おそらく最初はモーフ自体が画面の左上にあるため、得られる座標値は0@0となる。
(たいていのコンピューターグラフィックスシステム同様、Morphicでも画面左上が原点(0,0)となっている)
この座標値に対して、2@0という座標値を加える。座標値同士の加減算ではx成分・y成分それぞれについて計算が行われ、新たな座標値が生成される。この場合、(0+2)@(0+0)のような計算によって、2@0という座標値が得られる。
得られた2@0という座標値が、topLeft:というキーワードメッセージによってモーフに伝えられ、モーフの位置が元あった場所から右に2ピクセルほど変化する。これを連続的に用いればアニメーションのような効果が得られるので、後の回でゲームを作るのに利用するつもりである。
さて、座標値の計算式を書く上で間違えやすいのは、以下のように書いてしまうことである。

0@0 + 2@0

Smalltalkにおける@は、+や-と同様の中置演算子である。また、Smalltalkでは同じ種類の演算子において結合の優先順位は定められておらず、単に左から結合されていく。
つまり、上の式は以下のように解釈される。

((0 @ 0) + 2) @ 0

この場合、0@0という座標値に2が加えられる。座標値と普通の数値が加減算される場合、x成分・y成分それぞれに対して数値が加減算されるので、その答えは 2@2 となる。
さらに (2@2) @ 0 という計算が行われるにあたって、「座標値は@というメッセージを知らない」といったエラーが発生する。
MessageNotUnderstood
Smalltalkで実行時エラーが起こると、上のようなNotifier(ノーティファイア)が現れる。エラーについてはいずれ詳しく説明をするが、Notifierを見ると最上段にPoint(Object)とdoesNotUnderstand:が現れている。Notifierで最上段に表示されたものが、このNotifierを表示させている場所であり、この場合ObjectクラスのdoesNotUnderstand:メッセージとなっている。発生したエラーの具体的な意味は、座標値を表すPointクラスから上位のObjectクラスに至るまで、指定されたメッセージ(この場合は@)が見つからなかったということである。
話はどんどん脱線するが、先ほどの間違った式で発生するのはコンパイル時ではなく実行時だということに注意してほしい。つまり、式としては正しい形を成しているのだが、結果的に意味を持たないため実行時にエラーが発生する。Smalltalkはシンプルな文法と柔軟な仕組みで動作しているので、(慣れれば慣れるほど)コンパイル時エラーを出すのは他の言語ほど容易ではない。いずれ、そういったこともチュートリアルの中で説明しよう。
(第3回おわり)