新規トレイト作成用のテンプレートをクラスブラウザに出させるための細工


「トレイト」は 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: キーワード部分を既存のクラス定義に挿入して追加してくれます。



http://squab.no-ip.com:8080/collab/uploads/61/newtrait.png