新規トレイト作成用のテンプレートをクラスブラウザに出させるための細工
「トレイト」は Squeak で 3.9 から組み込みになった Ruby のモジュールライクな多重継承機構(Traits。この場合、複数形?)や、そのエンティティの名前(trait)、および、オブジェクトとしてのそれ(Smalltalk なら当然!w)が属するクラス名(Trait)のこと。
新しいトレイトは、クラスと同じように、いっけんテンプレートっぽい次のような式(メッセージ式)で定義できます。
Trait named: #NameOfTrait uses: {} category: 'Category-Name'
ところが、クラスブラウザのコードペインにこのテンプレートが出ない…というかクラスの定義用テンプレートと切り替えるためのメニュー項目などが見つからない。いちいち上のような式をタイプするのは面倒なので、そのための機構はないか(見つけられないだけできっとあるだろう…と)探してみることに。
具体的には、手始めに、まず、このテンプレートで特徴的な「uses:」を選択して cmd/alt + shift + e で method strings with it 〜文字列リテラルとして「uses:」をその記述内容に含んでいるメソッドを探し出す機能〜 を起動します。すると…、
Trait class >> newTemplateIn: categoryString ^String streamContents: [:stream | stream nextPutAll: self name; nextPutAll: ' named: #NameOfTrait'; cr; tab; nextPutAll: 'uses: {}'; cr; tab; nextPutAll: 'category: '; nextPut: $'; nextPutAll: categoryString; nextPut: $' ]
という、くだんのテンプレート式を文字列として生成しているメソッドを発見。そこで、改めてこれの senders of it (alt/cmd + n) を探すと、Browser >> #contents で editSelection(コードペインの表示モード)が #newTrait であるときにコールされている模様。
ならば…と「newTrait」を選択して senders of it (alt/cmd + n) をすると、ずばり editSelection := #newTrait している Browser >> #newTrait というメソッドといっしょに、
Browser >> addSpecialMenu: aMenu aMenu addList: #( - ('new class' newClass) ('new trait' newTrait) -). self selectedClass notNil ifTrue: [ aMenu addList: #( ('add trait' addTrait) -) ]. aMenu addList: #(-). ^ aMenu
を発見。ちゃんとあるじゃんかと、これの senders of it (alt/cmd + n) を調べれば、それが探していた答え…と思いきや、ポップアップで「There are no Senders of addSpecialMenu:」だと。なんだってーっ!
しかたがないので、Browser >> #classListMenu:shifted: に、そこでこさえているメニュー(aMenu)のアタマに #addSpecialMenu: するように書き加えてみました。
Browser >> classListMenu: aMenu shifted: shifted
ServiceGui browser: self classMenu: aMenu.
ServiceGui onlyServices ifTrue: [^aMenu].
shifted
ifTrue:
[^ self shiftedClassListMenu: aMenu].
self addSpecialMenu: aMenu.
aMenu addList: #( ...
こうしておくことで、クラスブラウザのクラス一覧ペイン(上段左から二番目の枠)の黄ボタンメニューから new trait でトレイト定義用のテンプレートを呼び出せます。普段のクラス定義用を再び呼び出すときは new class 。すでに定義済みクラスをブラウズしているときは add trait コマンドが現われるので、それを選択して出てくる a FillInTheBlank(入力欄)に使用(use)したいトレイト名を入力して指定することで uses: キーワード部分を既存のクラス定義に挿入して追加してくれます。