Upload
masashi-umezawa
View
45
Download
1
Embed Size (px)
DESCRIPTION
クラス名やメソッド名に改行がつかえるようにSmalltalkを拡張するとどうなるかという話。アスキーアートでメッセージ送信
Citation preview
第27回 Smalltalk勉強会 - Smalltalkの超能力
2010 Masashi Umezawa
動機
もっとクラス名、メソッド名をわかりやすくできないか? 長い名前とか、読むのが大変
ぱっと見ただけでわかるほうがいい
クラス名やメソッド名で改行つきの文字列を
使えれば、表現力が格段と高まるのではないか?
例
いらないクラスということがすぐにわかる
Object subclass: #'/ \
/ ─ ─\/ (●) (●) \ よく考えたら俺いらないな| (__人__) |/ ∩ノ ⊃ /( \ / _ノ | | .\ “ /__| |
\ /___ /'
instanceVariableNames: ''classVariableNames: ''poolDictionaries: ''category: 'Test-Multilines'
実装にあたって技術的には簡単
もともとクラス名やメソッド名はSymbolのインスタンス
Symbol自体には改行を含めることができる
○ #'改行文字列' のようにシングルクォートでくくればよい
開発環境の制限を外していくだけ
Multiline class
クラス名の先頭文字と使える文字に改行を追加
Character >> canBeGlobalVarInitialself = Character cr ifTrue: [^true].^ (EncodedCharSet charsetAt: self leadingChar)
canBeGlobalVarInitial: self.
基本これだけ
Multiline method (1)
開発環境の抵抗がなかなか強かったので、メソッド追加で対処
ClassDescriptiopn >> addAAMethod: aa body: bodyCode| code aaSymbol |code := 'tmp' , String cr , bodyCode.aaSymbol := aa asSymbol.self compile: code classified: ''.self addAndClassifySelector: aaSymbol
withMethod: (self methodDict at: #tmp)inProtocol: 'AA' notifying: nil.
self removeSelector: #tmp
Multiline Method (2)
各クラスのMethodDictionaryをいじってあげればよい tmpという名前でまずメソッドをコンパイル
コンパイルされたバイトコード(CompiledMethod)をアスキーアート(AA)をキーとして登録しなおす
tempのメソッドは消しておく
これでできた!
パーサライブラリの拡張 (1)
ワークスペース等で実行しやすいように既存のSmalltalkパーサライブラリを拡張する
DSL系を実装するには常套手段
Smalltalkでは自分をコンパイルするコンパイラクラスをクラス毎に指定できる
○ compilerClassメソッドのオーバーライド
今回は単にデフォルトのスキャナに手を入れるだけ
パーサライブラリの拡張 (2) スキャナにバッククォートのトークンを加える
AAをバッククォートで囲むと、クラスやメソッドの識別子としてパースされるようにしたいため
Scanner class >> initialize...newTable at: $` asciiValue put: #xBackQuote....
バッククォートを選んだ理由 他で使われていない
存在感が薄いのでアスキーアートを邪魔しない
パーサライブラリの拡張 (3)Scanner >> xBackQuote
self step.buffer reset.[hereChar = $`
and: [aheadChar = $`ifTrue: [self step. false]ifFalse: [true]]]
whileFalse: [buffer nextPut: self step.(hereChar = 30 asCharacter and: [source atEnd])
ifTrue: [^self offEnd: 'Unmatched string quote']].self step.token := buffer contents asSymbol.tokenType := #word
まじめに読む必要なし
xSingleQuoteメソッドをパクる
tokenTypeを#wordにする => 識別子になる
デモ AAクラスの定義
AAメソッドの定義
実行`
|┃三 ∩___∩|┃ | ノ ヽ|┃ ≡ / ● ● | きたクマー!
____,|ミ\___| (..●..) ミ|┃=___ |∪| \|┃ ≡ / ヽノ 人 \ ガラッ` new
`/⌒ヽ
∩ ^ω ^) うはwww| ⊂ノ
| _⊃ し ⌒`
まとめ
Smalltalkで、内部DSLをつくるのは非常に簡単
グラフィカルな表現もお手のもの
まじめな開発ではAAクラスとか使わないでください