Smalltalkは以前も触っていて、一度熱がさめたのですが、今年はLispもそうですが、Perlなどの他の好きな言語も真面目に取り組む事にしようと決めたので
Perlをある程度復習し終わったと判断して、Smalltalkを復習しはじめました。しばらく触っていないと本当に忘れていますね。
以前にL-System(リンデンマイヤーシステム:植物などの"成長するオブジェクト"を数学的な集合の要素の置換で表現する数理モデル)に興味を持ったときに
L-SystemをSmalltalkのクラスにして見た事がありました。クラス定義は以下の通りです。
Object subclass: #DOLSystem instanceVariableNames: 'V W S P' classVariableNames: '' poolDictionaries: '' category: 'L-System' DOLSystem >> initialize super initialize. V := Set new. W := ''. S := Set new. P := Dictionary new.
(あとはat:putなどの基本的なメッセージを用意してあります。)
そして、実際に10世代目の文字列をかえすメッセージは
gen: n | newV word tmp | newV := W. tmp := ''. n timesRepeat: [ newV do: [:each | (S includes: each) ifTrue: [tmp := tmp, (each asString)] ifFalse: [ word := P at: each. tmp := tmp, (word asString)].]. newV := tmp. Transcript cr; show: newV. Transcript cr; show: '<---------------->'. tmp := '']. ^newV.
のように定義されています。
使用例は以下のような感じです。
| dol pen stackp degp | dol := DOLSystem new. dol Sadd: $+. dol Sadd: $-. dol Sadd: $[. dol Sadd: $]. dol W: 'F'. dol Pat: $F put: 'FF-[-F+F+F]+[+F-F-F]'. dol gen: 4. pen := Pen new. pen color: Color random. stackp := Stack new. degp := Stack new. Display restoreAfter: [ Display fillWhite. (dol gen: 5) do: [:each | each = $F ifTrue: [pen go: 3]. each = $+ ifTrue: [pen turn: 22.5]. each = $- ifTrue: [pen turn: -22.5]. each = $[ ifTrue: [stackp push: (pen location). degp push: (pen direction).]. each = $] ifTrue: [pen location: (stackp pop) direction: (degp pop) penDown: true]. ]].
このサンプルが掲載されていたのはABOPです。この本にはもっと様々なサンプルが書かれていますので
いろいろ実装してみるのも面白いかと思います。
このL-SystemのSmalltalkのstファイルは、以下に置いてあります。
http://poketo7878.dip.jp/Download/L-System.st