アラン・ケイの“オブジェクト指向”というアイデアをもとに(非同期処理などいろいろ足りていないながらも──)比較的忠実に実装された1970年代の非常に古いSmalltalk-72で遊んでみるシリーズです(なお最新のSmalltalkについては Pharo などでお楽しみください!)。他の記事はこちらから→Smalltalk-72で学ぶOOPの原点 Advent Calendar 2019 - Qiita
(サンプルコード「joe the box」(turtleにplace追加、squareとboxの定義)の続き)
「is」メソッドの追加
今のままではjoeやjill、つまりboxクラスのインスタンスたちは、メッセージ「is …」に対してしかるべく振る舞えず、untypedということになってしまいます。なお、?は「~」で入力できます。

これにきちんと答えられるようにboxクラスにisメソッドを追加しましょう。Smalltalk-72操作マニュアルの Page 22 には、学習目的でISITを使わないちょっと長めの素朴な記述が紹介されています

が、ここでは素直に既に解説済みのISITを使って簡単に済ませてしまいましょう。

「's」メソッドの追加
これまた今のままでは、せっかく位置も変更できるように用意されたインスタンス変数xやyが使えません。「xメソッド」「yメソッド」といったアクセッサーを用意するのも手ですが、ここはもう少し柔軟に対応できる'sメソッドを定義することで対処します。
既にご紹介した'sメソッドのイディオム(⇑⦂ eval、もしくは⇑(:☞) eval)は、メッセージの続きのトークンもしくは配列を評価せずに取り込んで(⦂、もしくは(:☞))からあらためて評価し(eval)その結果を返す(⇑)というものでした。
isメソッド同様、addtoアクションを使ってboxクラスに簡単に追加できます。

ただしこの定義の場合、ゲッターとして使うときは欲しい変数を指定するだけで済むのですが──

xに別の値を代入しようとすると、そのための式を括弧でくくって与える必要が生じます。

ここは「joe's x ← 64」などとスマートに書きたいところですが、⇑⦂ evalのままでは「joe's x」で式が完結し、その返り値である数値「127」に改めて「← 64」が送られることになるため、結果、エラーが発生してしまいます(数値は← …メッセージに応答できないため。仮に応答できても望んだ結果にはなりませんが…)。

そこで、あらためてSmalltalk-72操作マニュアルの Page 22 に紹介されている'sメソッドを見てみると──

取り込んだトークンをいったん一時変数「var」に代入し(☞var←⦂.)、続くメッセージが「←」なら(∢ ←⇒(…))その後に続くメッセージを評価して取り込んでから「var」に入った変数に代入して値をリターン(⇑var←:)、そうでなければ改めて取り込んだトークンを評価(変数ならその値を得る)して結果をリターンする(⇑var eval)という、ちょっと凝った処理をしています。この定義に差し替えて期待通り振る舞うか試してみましょう。
すでに「's」メソッドを定義済みなので、与えたコード片を単純にコード末尾に追加するだけの「addto」アクションは使えません。そこで「edit」アクションでエディターを起動し、Replaceで「's」メソッドを差し替えます。


Exitでエディターを抜けて元のREPLに戻れば、今度は「joe's x ← 64」が期待通り動作するようになっているはずです。

こんな記述も可能になります。

「's」はRubyのinstance_eval相当なのですが、とても自然に書き下せていますね。このように文法を気軽に拡張できることは、たいへん柔軟でパワフルである反面、なんとも怖ろしくもあります(そしてそれが次の世代のSmalltalk-76が同様の実装にならなかった理由のひとつであり、また、LISPの強い影響下にありながらRubyにマクロがない理由のひとつでもあるわけです)。
Smalltalk-72操作マニュアルには、この他にmoveメソッドの追加や、そのバリエーション、redrawメソッドを使った別のboxの実装なども紹介されているので是非試してみてください。