“最悪のHello World”を Squeak Smalltalk で


JAPH (Just Another Perl Hacker)みたいなもん? - ときどきの雑記帖 i戦士篇 経由での http://blog.cnu.jp/2009/07/08/hello-world-2/Squeak Smalltalk ならではの駄目さ加減でトライ。

World findATranscript: nil; withAllOwnersDo: [:owner |
   Transcript cr; show: (
      ((thisContext sender method selector asString replaceAll: $A with: $e;
         findBetweenSubStrs: 'tw') second asLowercase capitalized), ' ',
      (Smalltalk keyAtValue: thisContext sender receiver))]

"=> Hello World "


replaceAll: $A with: $e がチトつらいかな…。^^;



さすがに毎度おなじみの Ruby に直訳…とかは不可能なので、以下、野暮を承知で簡単な解説。


Squeak(の Morphic GUI フレームワーク)では、現在のデスクトップは World というグローバル変数に代入されています(これをあとで利用しています)。findATranscript: nil はデスクトップに送ることで、トランスクリプトと呼ばれる標準出力もどきのウインドウを現在のデスクトップに表示する(すでに表示されているときは最前面に持ってくる)ためのメッセージです。

「;」はカスケード式を表わす記号で、以降のメッセージを直前の式のレシーバに送ることを意味します。ちなみに直前の式の結果(返値)は破棄されます。

#withAllOwnersDo: は、マウスポインタやデスクトップを含めたウィジェットのオーナーを再帰的に列挙して、レシーバ自身と全オーナーについてパラメータとして与えたブロックを実行(評価)します。

ただ、デスクトップにはオーナーはいないので、この場合、ブロックは一回しか評価されません。その1回しか評価されないブロック内に、以下で解説する「Hello World」出力コード本体が記述されています。

thisContext は実行中のコンテキストを参照するための擬変数で、今はブロックコンテキストを返します。sender はレシーバであるコンテキストの呼び出し元のコンテキストを返させるメッセージなので、このブロックを評価しているメソッド、つまり #withAllOwnersDo: のコンテキストを返します。

method は実行中のメソッド本体を、selector はそのメソッド本体にメソッド名(セレクタ)を返させるメッセージなので、結局、#withAllOwnersDo: というシンボルが得られるわけです。ここから hAllO を取り出し、$A を $e に置き換えて(つらい…)Hello を作っています。

World のほうは、レシーバであるデスクトップがグローバル変数 World に代入されていることを利用して、グローバル変数を管理しているグローバル変数 Smalltalk からデスクトップ(a PasteUpMorph)と関連づけされているキーを抜き出して利用しています。本当は ActiveWorld というのもあるのですが、たまたま #keyAtValue: が #World しか返してこないので割愛しました。