Classboxes で遊ぶ
Matz にっき 経由で。将来、Ruby にも採用される…かもしれないw、アスペクト指向っぽいモジュールシステム、Classboxes で遊んでみました。
Classboxes は、クラスボックスと名付けられたクラス横断モジュールの組み込みを通じて、既存メソッドを置き換えたり、クラスに新しいメソッドを追加することを可能にする機構。Squeak の Smalltalk で実装を試され、Java 向けにも Classbox/J として移植されているようです。
http://www.iam.unibe.ch/~scg/Research/Classboxes/
このページには、The Squeak version will be soon available. とあるので、それならば…と、ダウンロードが可能な OS X 向けの Classbox/J を試してみたのですが、残念ながら手元の環境では動かすことができませんでした。
で、実際に動かすことはかなわないのかとあきらめていたのですが、SqueakMap を見ると、Classbox と ClassboxBrowser としてパッケージが存在することが分かりましたので、これで試してみようと思います。
インストール
SqueakMap パッケージの説明にある URL にはアクセスできないのですが、次の URL に Squeak 版 Classboxes の簡単なチュートリアルを見つけることができました。
http://smallwiki.unibe.ch/classboxes/classboxtutorial/
ここの記述によると、Squeak のバージョンは 3.7b-5868 とありますので、これに近い、3.7-5989 を squeak.org の ftp より入手することにします。
http://ftp.squeak.org/3.7/Squeak3.7-5989-basic.zip
このバージョンに対応する VM や .sources も同じディレクトリ経由より入手可能です。
Sqeuak システムが起動できたら、デスクトップメニュー → open... より SqueakMap Package Loader を呼び出します。いくつかの確認がポップアップしますが、すべて Yes で答えます。
SqueakMap Package Loader が起動したら、左上のペインに classbox と入力して accept するなどして、左側のリストペインより Classbox パッケージを探します。
図のように項目を展開すると、いくつかのバージョンがリストされますが、136 がチュートリアルレベルの作業では安定、かつ、期待する動作をしてくれるようですので、これを選んで黄ボタンメニュー(ペイン右上、スクロールバーの直上にあるボタンをクリック)より install を選択しインストールします。ClassboxBrowser についてもほぼ同時期の 68 を選んでインストールしましょう。
あと、このバージョンでは Classbox Workspace がうまく機能せず式が評価できないので、ちょっと細工をしてとりあえず動くようにするためのチェンジセットをこしらえてみました。これをデスクトップメニュー → open... → file list で選択、install してください。
http://squab.no-ip.com:8080/collab/uploads/61/CbWkspQuickFix-sumim.cs.gz
クラスボックスブラウザ、クラスボックスワークスペースの起動
デスクトップメニュー → open... に Classbox Browser(クラスボックスブラウザ)と Classbox Workspace(クラスボックスワークスペース)が追加されています。
ここまでできたら、デスクトップメニュー → save as... で Classboxes.image などとして環境を保存しておくことをお薦めします。
クラスボックスの新規作成
クラスボックスブラウザの左上のペインの黄ボタンメニューの create classbox、もしくは、クラスボックスワークスペースの Select Classbox ボタンをクリックしてポップアップするメニューの new Classbox により、新しいクラスボックスを作成できます。ここでは、Cb1 とでもしておきましょう。
クラスボックスへの Object のインポートと新規クラスの定義
左上のペインで、クラスボックス Cb1 を選択した状態で黄ボタンメニューより import Object from System を選択します。すると、Object クラスをインポートしてクラスボックス内で参照できるようになります。続けて、下のペインにあるクラス定義のテンプレートの中の #NameOfClass を #C に置き換えて accept (alt/cmd + S) します。I Object の上に C が現われます。
メソッドの定義
上段三番目のペインの no messages をクリックして選択したあと、下のペインの内容を次のように置き換えて accept します。その際現われる Please type your initials: と尋ねる a FillInTheBlank にはニックネームやイニシャルなどを適当に答えて accept します。
m ^ 'Cb1::C >> #m'
no messages が as yet unclassified に変わりますが、これをクリックすると今、定義したメソッド m が右側のペインに現われるので(こうした挙動はバグです)、改めてこの m をクリックすれば下のペインに先ほど accept した内容(当然、入力したものと同じ内容)が現われます。
別のクラスボックスの定義
同様にして Cb2 に C >> #m を定義しましょう。いったん、左端のペインの Cb1 をクリックして選択を解除します(バグ回避のため、この操作は重要です)。そして改めて黄ボタンメニューから create classbox を選んで Cb2 を定義、以下、上述の操作を繰り返してクラス C とメソッド m を定義します。ただ、メソッドの m の定義は区別が付くようにちょっとだけ変えておきます。
m ^ 'Cb2::C >> #m'
これで準備は完了です。
クラスボックスを切り換えて式を評価する
クラスボックスワークスペースをアクティベートし、次の式を print it(alt/cmd + P)します。
C new m
デフォルトではクラスボックスは選択されていないので、C は未定義とコンパイラに叱られます。
=> UnknownReference: Reference not found C
改めて Select Classbox ボタンをクリックし、ポップアップから Cb1 を選んで再び print it すると次のような文字列が式の評価結果として挿入されます。
'Cb1::C >> #m'
delete で出力文字列を削除後、Cb1 の代わりに Cb2 を選んで同じ式を評価した場合は、
'Cb2::C >> #m'
と結果が変わります。クラスボックスブラウザで、現在選択されているクラスボックスが何かは、ウインドウのタイトルバーの表示(Current Classbox: Cb2 など)で分かるようになっています。
通常のワークスペースなどを使う場合は、チュートリアルにあるように Classbox class >> #get: でクラスボックスを得てそれに evaluate: expressionString を送信して評価すればよいようです。
(Classbox get: #Cb1) evaluate: 'C new m' " => 'Cb1::C >> #m' "
とりあえずは、こんなところで。