概要
@sumim さんの Squeak Smalltalkでズンドコキヨシ に触発されて、Pharo
Smalltalk の Announcement を使ってズンドコキヨシをしてみました。
キヨシが「ズン」「ズン」「ズン」「ズン」「ドコ」と歌うと観衆が「キヨシ!」と合いの手を入れます。
方針
キヨシはプロの歌手です。沢山の聴衆に向かって歌います。なので、キヨシと観衆が直接結合するのはよろしくありません。
スターと聴衆の間には線引きが必要なのです。
そこで、 Pharo Smalltalk の Announcement メカニズムを使って分離します。
実装
キヨシの実装
クラスを以下のように定義します。
Object subclass: #Kiyoshi
instanceVariableNames: 'announcer'
classVariableNames: ''
category: 'ズンドコキヨシ'
announcer の遅延初期化も含めたアクセサを定義します。
announcer
^ announcer ifNil: [ announcer := Announcer new ]
これでキヨシは聴衆に向けてアナウンスを飛ばすことができるようになりました。
では、アナウンス内容を定義しましょう。
Announcement subclass: #Phrase
instanceVariableNames: 'word'
classVariableNames: ''
category: 'ズンドコキヨシ'
そしてPhraseにアクセサやインスタンス生成を定義します。
word
^ word
word: aString
word := aString
with: aString
^ self new word: aString
Kiyoshiは歌います。
sing: aString
Transcript show: aString.
self announcer announce: (Phrase with: aString)
トランスクリプトウィンドウに言葉を表示して、それを歌詞(Phrase)としてアナウンスします。
プロともなれば、持ち歌のフレーズはソラで歌えます。当然です。
ズン
self sing: 'ズン'
ドコ
self sing: 'ドコ'
もちろんアドリブだってできます。
singRandom
(Random new nextInt: 5) = 1
ifTrue: [ self ドコ ]
ifFalse: [ self ズン ]
聴衆の実装
聴衆は、アナウンスを聴いて、「ズン」「ズン」「ズン」「ズン」「ドコ」ときたら、「キヨシ!」と合いの手を入れます。
Object subclass: #Audience
instanceVariableNames: 'memory'
classVariableNames: ''
category: 'ズンドコキヨシ'
まずは、キヨシの歌を聴きに行きます。
listenTo: aKiyoshi
aKiyoshi announcer subscribe: Phrase send: #hear: to: self
キヨシが歌詞(Phrase)をアナウンスしたら、自分に聞かせろ(self hear: aPhrase)ということです。
では、聞きましょう。
hear: aPhrase
self memory add: aPhrase word.
(self memory endsWith: #('ズン' 'ズン' 'ズン' 'ズン' 'ドコ'))
ifTrue: [
self sing: 'キヨシ!'.
self memory removeAll ]
ああ、もちろんmemoryの遅延初期化アクセサも定義しないといけません。
memory
^ memory ifNil: [ memory := OrderedCollection new ]
そして合いの手。
sing: aString
Transcript show: aString; cr
できた!
テスト
では、プレイグラウンドとトランスクリプトウィンドウを開いて、以下のコードを実行してみましょう。
kiyoshi := Kiyoshi new.
audience := Audience new.
audience listenTo: kiyoshi.
そして、
kiyoshi ズン;ズン;ズン;ズン;ドコ;ズン;ズン;ドコ;ドコ;ズン;ズン;ズン;ズン;ドコ
を実行すると、トランスクリプトウィンドウに
と表示されます。やった!
ではアドリブを効かせてもう一度!
100 timesRepeat: [ kiyoshi singRandom ]
するとこんな感じに。
まとめ
Pharo Smalltalk の Announcement という放送メカニズムを使って、キヨシと聴衆を強結合させないでズンドコキヨシをしてみました。
旧来のchanged:とupdate:に基づく放送メカニズムに比べて、update:にボイラープレートが必要なくなったのと、シンボルだけでなく放送内容のクラスを使って必要な放送を選択できるので、ちょっと自由度は高くなったかなと思います。