Smalltalk-72で遊ぶOOPの原点:スケジュールされたオブジェクトのアクティベートに「step」メッセージを使用する

アラン・ケイの“メッセージングによるプログラミング”という着想に基づき(非同期処理などいろいろ足りていないながらも──)比較的忠実に実装された1970年代の非常に古いSmalltalk-72に実際に触れてみるシリーズ 第2弾です(なお最新のSmalltalkについては Pharo などでお楽しみください!)。

今回は謎言語「Smalltalk-71」で書かれたスペースウォー・ゲームSmalltalk-72に移植して動かすことを目指します。前回(2019年)を含む他の記事はこちらから→Smalltalk-72で遊ぶOOPの原点 | Advent Calendar 2023 - Qiita


愚痴

前回、オブジェクトがアクティベートされただけで、メッセージが送られてこなかったり、あるいは知っているメッセージを受け取らなかった場合に何もしないのが Smalltalk-72 でのオブジェクトの振る舞いの基本である、というようなことをコメントしました。

もちろん、今回の spaceshipstickインスタンスの使い方は Smalltalk-72 のオブジェクトとしてはいろいろ問題ことはわかっていたのですが、元の Smalltalk-71 の記述に寄せたり、明示的にメッセージを送らずともプロシージャのように振る舞うオブジェクトもカッコイイかなぁ…などと軽く考えたのが運の尽きでした。

果たして次から次へ問題が噴出し、回避策を見いだせないかとただでさえ少ない時間を溶かしつづけ、未だにクリスマスに到達できないまま現在に至っております^^:

たとえば、spacewar schedule <spaceshipのインスタンス> とした場合、画面になぜか宇宙船が二度ほど描かれてしまいますよね。これなんかは obset がこの種の定形外のオブジェクトを扱えない(具体的には参照をうまく扱えていない)のが原因のひとつだったりします。

なんなわけで、だんだんつらくなってきたので一部仕様を変更して、標記通り、スケジューラ spacewar に登録するオブジェクトについては、アクティベートだけでなく、stepメッセージを受け取った場合だけ処理をするように変更します。すみません。

なお、spacewar に絡まない stick まで手を入れるとなるとかえって大変になりそうなので、これはそのままにします。どうぞあしからず。

to spacewar x y : : objects (
    (null objects ? ("objects _ obset))
    %schedule ? (objects _ :#)
    %delete ? (%all ? ("objects _ nil) objects delete :#)
    %run ? (repeat (objects do (each step))))

to spaceship : pilot thrust steer trigger numtorps locx locy speed direction time ftime llocx llocy ldir lthr (
    isnew ? (:pilot. "lthr _ :#thrust. :#steer :#trigger. 
        "numtorps _ "speed _ 0.
        "direction _ "ldir _ 0 + rand * 360.
        "locx _ "llocx _ rand between 50 462.
        "locy _ "llocy _ rand between 50 462.
        "time _ "ftime _ clock)
    %step ? (
        0 < clock - time + MOVELAG ? (
        "time _ clock.
        moveship.
        display ship))
)

to keysens (%step ? (repeat (kbck ? (stick process kbd) done)). #keysens)

「find all」の実装 へ続く )