Smalltalk-72で学ぶOOPの原点:あらためて「Hello, World!」と文字列操作

アラン・ケイの“オブジェクト指向”というアイデアをもとに(非同期処理などいろいろ足りていないながらも──)比較的忠実に実装された1970年代の非常に古いSmalltalk-72で遊んでみるシリーズです(なお最新のSmalltalkについては Pharo などでお楽しみください!)。他の記事はこちらから→Smalltalk-72で学ぶOOPの原点 Advent Calendar 2019 - Qiita


文字列操作…の前にクラス定義についてからの続き)

文字列の表示

文字列クラスstringの定義を再掲します。

f:id:sumim:20191208181441p:plain
[再掲] 文字列クラス`string`の定義

このprintの定義を読むと文字列を表示する方法は(REPLで、文字列に限らず、直前に評価した結果を自動的に出力する振る舞いを除けば──)2つあることがわかります。

ひとつは、文字列に対してprintメッセージを送ることで、もうひとつはそのprintを受け取ったときの振る舞いに書かれているようにdispというオブジェクトに対して← <文字列>というメッセージを送る方法です。やはりコードを読むことで分かるように、両者は同じではなく、前者は文字列の前後を'(クオート)で括って出力します。

f:id:sumim:20191208183006p:plain
2つの方法で「Hello, World」

なお、残念ながら「!」(エクスクラメーションマーク)はそのままキーをタイプしても(リターン)が表示されるだけで入力できないので、とりあえず前者の方法では今は諦めます。後者の方法では、文字列の代わりに数値を送ることで文字を出力できるようなので、「!」のグリフが割り当てられている17を送ることで対応しています。

参考まで、0から127までのコードの文字には次のようなグリフが割り当てられているようです。

f:id:sumim:20191208190820p:plain
0から127までのコードの文字に割り当てられているグリフ

上で使ったdisp ← <文字列>disp ← <文字コード>で文字列や文字が出力できる他に、printのコードを読んでいて気がつくのは、文字列に[<開始位置> to <終了位置>]を送ることでRubyのように部分文字列を取り出せる機能があることや、さらにfind first <文字コード>を送ってコードで指定した文字の位置を知ることが出来る機能があること、そして、これらの定義がstringには見当たらないことです。

どうやらクラス変数substr がこの謎の鍵を握っているようですがこれについてはまた改めて。

文字列の結合

今のSmalltalkでは文字列や配列の結合は,(カンマ)を使いますが、Smalltalk-72ではRubyなどと同様に+を使うようです。もちろんこれは演算子ではなく、+ <結合したい文字列>というメッセージです。

f:id:sumim:20191208184916p:plain
文字列同士の結合

ただ、下に再掲したvectorの定義を見ると分かるように、配列には+による結合は定義されていないので、このメッセージが使えるのは文字列だけであることがわかります。

f:id:sumim:20191208184701p:plain
[再掲] 配列クラス`vector`の定義(黄色および薄赤部分はCODE 3の擬似コード

f:id:sumim:20191208184947p:plain
配列で同じ操作をしようとすると…

f:id:sumim:20191208185050p:plain
エラーになる

ちなみに配列の操作にはvecmodという専用のアクションが用意されています。これについてもまた別の機会に。

f:id:sumim:20191208185536p:plain
配列操作用のアクション「vecmod」

継承が…ない!(クラス変数の利用)に続く)