アラン・ケイ の“オブジェクト指向 ”というアイデア をもとに(非同期処理などいろいろ足りていないながらも──)比較的忠実に実装された1970年代の非常に古いSmalltalk -72で遊んでみるシリーズです(なお最新のSmalltalk については Pharo などでお楽しみください!)。他の記事はこちらから→Smalltalk-72で学ぶOOPの原点 Advent Calendar 2019 - Qiita
(ユーザー定義クラス・アクションの一覧「defs」と定義の出力「show」 の続き)
対話ウインドウクラスdispframe
とそのインスタンス disp
画面の下の方に表示されている矩形領域はdispframe
という対話ウインドウクラスのインスタンス で、使用中のものはdisp
という変数に代入されています。
「disp」に代入された「dispframe」のインスタンス
例によってALLDEFSでto dispframe …
で始まるコードやコメントを読むとこのウインドウの使い方(応答できるメッセージやその送り方)が分かります。
たとえば、すでに何度か出てきているように← <ASCIIコード>
というメッセージを送れば指定したASCIIコードに割り振られた文字が、← <文字列>
というメッセージを送ればその文字列が表示される…とか、
「dispframe」クラスに定義されたメッセージ「←」への応答(コメントにて)
「← <文字コード >」、「← <文字列>」への応答
画面が汚れてしまったらdisp clear
で消して、disp display
で描き直すことができる…とか、です。
ウインドウ領域を消去するには「disp clear」
消去したあと、改めてウインドウを描き直すには「disp display」
一方で、「Open the ST-72 Manual」ボタンでダウンロードして読むことができる1976年刊の「Smalltalk -72 Instruction Manual」の記述にはある、ウインドウを移動したり(moveto
)、サイズを変える(growto
)といったいくつかのメッセージ
ここにある例のうち「hide」「moveto」「growto」は定義されておらずエラーになる
これらへの応答は、「ALLDEFS」ボタンで参照できる1974年のALLDEFSには(かつ、それに近いバージョンのALLDEFSで起動しているらしいこの処理系のメモリダンプにも)まだ実装されていないことも分かります。
また、マニュアルにある1976年ごろのバージョンには、新規ウインドウの作成、削除(閉じる)、大きさの変更、移動といったマウス操作も可能だったようですが、それらも当然まだ実装されていません。
1976年頃のウインドウ操作に関する記述(Smaltalk-72 Instruction Manual, pp 5-6)※このエミュレーター では使えません
これらは矩形領域の高速な描画を可能とするBitBLT
ルーチンが発明され、あるいはそれがマイクロコード化された後に実装された機能だと思われます。
BitBLT ルーチンへのアクセスに関する記述(Smalltalk -72 Instruction Manual, pp 42-43)※このエミュレーター では使えません
put <文字列> at <x座標> <y座標>
ウインドウ操作に関連する振る舞いが軒並み未実装ななか、かろうじて、任意の文字列を任意の場所に表示するdisp put <文字列> at <x座標> <y座標>
という式は使えるようです。
メッセージ「put <文字列> at <x座標> <y座標>」への応答を記述したコード
これは実質、ウインドウを移動しているコードなので、このメッセージを送ることでdisp
を画面の上の方へ移動してみましょう。ただしこのput …
メッセージは、レシーバーであるdispframe
のインスタンス (ここではdisp
)を移動しはするものの、指定した文字列を表示するだけでフレームの描き直しなどはしてくれません。そこで「disp display. disp clear」を続けて実行することで、枠やプロンプトの表示も行います。
「disp '' at 16 16」でウインドウを画面上部に移動し、「disp display. disp clear」で枠を描き直した結果
disp
に手をつっこんで('s
)縦の長さ(winht
とfrmht
)を変える
dispframe
のインスタンス 生成式やそれについてのコメント、
「dispframe」のインスタンス 生成式やインスタンス 変数についてのコメント
あるいはdispframe
インスタンス 化時(つまりdispframe
が直接コールされた結果、isnew
が非偽値を返すときに実行される──)isnew ⇒(…
以降の初期化コード片を読むと、ウインドウの高さはwinht
とfrmht
に保持されていることが分かります。
「dispframe」のインスタンス 生成時(「isnew」が非偽時)の初期化処理を記述したコード片
そこで、disp
に's (<評価したい式>)
を送って、直接これらのパラメーターを書き換えてしまいます。より多くの行数を表示できるように、バッファー(buf
)も増やしておきます。「disp display. disp clear」の追加も忘れずに。
「disp」の高さを無理矢理変えて描き直すと…
画面いっぱいに広がったウインドウ
任意の場所にスクロールさせることはできませんが、このくらいの縦幅があれば、クラスやアクションの定義を整形して表示するshow
アクションもかなり快適に使えます。
「show obset」をdo-it(\キー)してコード全体を表示させてみた様子
(サンプルコード「joe the box」(turtleにplace追加、squareとboxの定義) に続く)