ゆの in Smalltalk - みねこあ での召還をまんまとうけてw、各種言語向けのを参考に要件を手探りしつつ、みねこあさんよりご要望のあったスキャナ(字句解析器)に手を加えてしまう Smalltalk ならでは…の方向で。
なにしろ元ネタ「ひだまりスケッチ」をまったく知らないので、ハズしていたらごめんなさい。
まず、グローバル変数 X を定義。
Smalltalk at: #X put: 'ひだまりスケッチx365 '
続いて、スキャナのテーブルをいじって $/ を無効化。加えて #< の再定義と、X を監視するスレッドをバックグラウンドで走らせます。
| 番組名 | 番組名 := X. (Scanner classPool at: #TypeTable) at: $/ asciiValue put: #xDelimiter. X class compile: '< 告知 ^self, 告知'. [ [X = 番組名] whileTrue. (Scanner classPool at: #TypeTable) at: $/ asciiValue put: #xBinary. 番組名 class removeSelector: #< ] forkAt: Processor userBackgroundPriority
で、主役登場。
X / _ / X < '来週も見てくださいね!'
=> 'ひだまりスケッチx365 来週も見てくださいね!'
以下、解説。
まず、みねこあさんも苦心されているように _ が := と同じ代入の意味を持つ Squeak Smalltalk では、“ゆのっち”こと「X / _ / X」は Smalltalk 式として意味をなしません。この状況をどげんかせんと先に進めないわけです。
そこで、スキャナが作業用に用いるテーブルへの細工により、$/ をデリミタ(スペースやタブ、改行などと同様)であるかのようにスキャナを騙して解釈させることにします。この結果、$/ は無視され、コンパイル時に前述の式は
X := X < '来週も見てくださいね!'
と等価になります。
ここまでできればあとは簡単。並行してメソッド #< は、文字列の結合を意味するメソッド #, のエイリアスとして再定義してあるため、代入式の右辺の「X < '...'」は X に代入されている番組タイトルと引数として与えられた台詞を結合します。よってその値は、あらためて X に再代入されると同時に、そのまま代入式(つまり、元の式)の結果としても返される…という演出に使えるわけです。
さて一方、バックグラウンドで X の監視を行なっていたスレッドは、この再代入で値が変ったことを感知して待機のためのループを抜けます。続く、スキャナのテーブルの復旧と、再定義した #< の削除が行なわれ、これで全行程が完了します。
なお、後のことを考えなくてよいならこの別スレッドによる監視や復旧は不要なので、実質、下に示す二行(二つの式。うち、メソッドの定義は一つだけ!)で「X / _ / X < '...'」を評価可能にできた…というところも一応、他の言語には真似できない“ウリ”かと思います。
(Scanner classPool at: #TypeTable) at: $/ asciiValue put: #xDelimiter. (X := 'ひだまりスケッチx365 ') class compile: '< 告知 ^self, 告知'
こんなんでいかがでしょうか(^_^;)。>ご主人様
他にも続々と!