Squeakを使ってみる

シミュレーションをちょっと可視化するのに、tkinterとかwxとかの決まり事を毎回書くのもなんか面倒だし、かといって汎用化しようにもなかなか上手くいかない。ずうっと昔にウィンドウとか無い時代の古っちいX11のラッパーグラフィックスライブラリみたいなCライブラリを書いたことがあるけど(既に配布していた大学のURLが404w。なぜかrubyの拡張ライブラリだけ残ってる)、流石に時代遅れかなとか。
シミュレーションと言えばオブジェクト指向オブジェクト指向環境と言えばSmalltalk。んで、面白そうだからってんで Squeakをちょっと使ってみることにした。

インストール

http://squeak.org/Download/
右上のショートカットリンクはなぜか Linux-> MacOSX, mac -> win32と一個ずれてる。多分webコード中のインデックスの間違いだろうなあとか思うんだけども。一応メール出しといた*1。しかし、この辺りでちょっと混乱し始める。
SqueakVM上でイメージファイルを実行する方式で、イメージファイルさえ持っていけばどこの環境でも同じように作業ができる。動作環境をフリーズドライしたImageファイル、ソースを格納するSourceファイル(Imageのサイズ増大を避けるため)、変更情報を格納する一種のログファイルであるChangeファイル(障害時に復旧が可能)、の3ファイルに分かれているんだけど、これに加えてVMバージョンとこれらファイルのバージョン関係が結構初心者にとってはカオス。ちゃんと考えれば、Image & ChangeはImageの現在のbranchのバージョン、Sourceはその前のスナップショットバージョン、VMは別とわかるんだけど、結局ちょっと日和って日本語版を
http://swikis.ddo.jp/umejava/48
から拾ってくることにした。上記サイトにあった「All-in-oneパッケージ (NEW:2009/07/08更新!!)」を使った(多謝!)。VMバージョンが4.1.1beta2U, Image/Changeファイルが 3.10.2-7179-basic-J、SourceファイルがV39という感じ(結構こんだけでも混乱してたりして)。
ともかくも動作する環境が手に入った。

基本ツール

実行するとウィンドウ上にウィンドウシステムが構築される。Smalltalkで遊びたい僕にとって基本となるツールは(とりあえず)Workspace, Transcript, SystemBrowserの3つ。Workspaceはプログラムなんかを書くちょっとしたメモ。Emacsの *scratch*みたいな感じ。Transcriptはコンソール。ここに出力できる。SystemBrowserはクラスビューア+Workspaceみたいな感じ。実はどこに書いても命令文は実行できるんだけど。。。
ともかくこんだけをツールタブから出しておく。

基本アクション

do it, print it, inspect itの3つ。do it は選択した、またはカーソルがある場所の命令を実行。print it は結果を同じ場所に表示する(eval-print-last-sexp状態)。inspect it は結果オブジェクトのビューアウィンドウが立ち上がる。それぞれ[Alt/Apple] + d,p,iでワンタッチ実行。やりやすい。

基本文法

代入

代入は _ (アンダースコア)、または := (ちなみに= は同値判定。 ==が同一判定)。他の処理系のことを考えると :=のほうが好ましいらしい。
#説明を見るとアンダースコアを入力すると自動的に ←になる、とかあったんだけどならない orz
# ^はちゃんと↑になるのに・・・

メッセージ文

ごく普通。 の順に書くだけ。確かにObjective-Cとおんなじ。似て非なるのはブロック構文くらいかな。
3種類のメッセージ式(なんかやたら3が多いのはやはり美学かな)。

  1. 単項メッセージ
  2. 2項メッセージ
  3. キーワードメッセージ

優先度はこの順番。
単項はメッセージ一個だけの奴。

star := MorphStar new.
star openInWorld.

のような感じ。
2項メッセージは普通の演算子

3+3 "print it  >> 6"

一つ注意点:左結合しかしないので、明示的に括弧で順序指定しないと

1+2*3 "print it >> 9"

とハマる。
キーワードはObjective-C経験者にはなじみ深い奴。

star x:100 y:100

おぉ、座標は左下原点なのだね。なるほど。
ちょっと便利だな、と思ったのが <クラス名> browseを送ると SystemBrowserに該当クラスの情報が出ること。これで色々調べまくれる。

ブロック

lambdaというか、なんというか、rubyのブロックそのもの。あれsmalltalkから拝借してたんだ。
僕には(内部的にどうであれ)rubyブロックはどちらかというと構文の一部っぽく感じられるんだけど(実際ブロック単体ではオブジェクトにならない)

10.each { |i| #改行するのが自然に感じる
  puts i
}

smalltalkのはまんま式だ。

blk := [:i| Transcript show: i; cr]
1 to: 10 do: blk   "1\n2\n...10\n > Transcript"

blk value:999  "999 > Transcript"

で、制御構文は(厳密には)存在せず、このブロックを利用している。

*1:そろそろなおってるかな?