はじめに
Smalltalkを短く伝える方法という記事を見て、自分だったらこうかなと思ったことを記事にしてみました。なんか老害な感じもします。
なお処理系にはPharo Smalltalkを使います。
1から10までの和を出してみる
以前いろいろな言語で流行っていたみたいですが、Smalltalkでは普通にこうですね。
(1 to: 10) sum
「1から10までを足す」がそのまま表現されていると思います。
"Inspect it" (Alt or Cmd + i)で確認すると当然ながら55です。
あるオブジェクトを参照している他のオブジェクトの配列を得る
いわゆる逆参照というやつです。
yourObject pointersTo
で得られます。
では、「なにか適当なウィンドウを取り出し、それを参照しているオブジェクトの配列をインスペクト」してみましょう。
書き下すとこんな感じです(元の日本語より短いですが)。
NautilusWindow someInstance pointersTo inspect
"Do it" (Alt or Cmd + d)でドカーンとインスペクタが開きます。
あるクラスの何か適当なインスタンスを得るには#someInstance
を使うのですね。
では調子に乗って、現在実行中のプログラムで、もっとも人気のあるMorphインスタンスを見つけてみましょう。ちなみにMorphとは画面に表示されているもろもろのオブジェクト(ウィンドウやボタン、ラベルなど)のことを指します。
#pointersTo
を送った結果の配列のサイズがもっとも大きいやつが、もっとも人気のある(参照されている)オブジェクトということなので、以下のようになるでしょう。
[(Morph allSubInstances detectMax: [:each | each pointersTo size]) inspect] fork
Morph allSubInstances
で、Morphの(サブクラス群も含めた)すべてのインスタンスが得られます。
#detectMax:
で、引数ブロックの評価結果が最大のものを取り出すことができます。
5000以上ものMorphがうごめいている中、その逆参照を求めるというのは、実はかなり重たい処理になるので、さらに全体をブロックで囲ってfork
しています。こうすると別のスレッドで動いてくれるので、その間に他のことができて便利です。
...ご飯食べてきました 。インスペクタが開いています。
優勝はMorphTreeMorph
さんだったようです。名前からしてヤバそうです。
インスペクタ下部のペインで実際の逆参照の数を表示させてみましょう。"Print it"(Alt or Cmd + p)します。
self pointersTo size
あるディレクトリ下のファイルでサイズが最も大きいものを拡張子別に集計してCSVとして書き出す
「メタメタしているのはわかったけれど実用性皆無」というツッコミを受け、実用的なものも書いてみます。
FileStream newFileNamed: '../sizes.csv' do: [:str |
((('.' asFileReference allChildren groupedBy: [:each | each extension]) collect: [:files | files detectMax: [:each | each size]]) values sort: [:a :b |a size >= b size]) do: [:file |
str nextPutAll: (', ' join: {file size. file extension. file fullName}); lf.
]
]
「カレントディレクトリ('.')以下のすべてのファイル群に対して、拡張子ごとにグルーピングして、サイズが最大のものについて、降順に並べた上で、"{サイズ}, {拡張子}, {パス名}"のフォーマットで、親ディレクトリの'size.csv'というファイルに書き込む」という処理です。
一回も代入を使わず、すべてメッセージ送信でまとめているところがエレガントな感じです。
できあがったsizes.csvを開くと以下のようになっていました。やはりExcelは便利ですね。
ということで普段の仕事でもSmalltalkを使ってみても良いのではないでしょうか。最近周りにSmalltalker、じわじわと増えてきています。