GNU Smalltalk の“あなごる”向け TIPS


関係のない Squeak Smalltalk でも、つい、変数を一文字にしたり、スペースを極力省いて書いてしまって苦笑いをするほど中毒性が高くてキケンきわまる“あなごる”こと shinh さんの anarchy golf ですが、ダメだダメだと文句をいいつつも GNU Smalltalk のタコさかげんにも慣れてくるもので、それなりにノウハウめいたものが蓄積されてきたところをざっとメモ。


▼アルファベットに続く式の区切りの「.」(ピリオド)の直後にアルファベットはNG(要スペース)

Squeak Smalltalk にはない名前空間のドット記法と混同されるようです。


▼数字に続く式の区切りの「.」(ピリオド)の直後に数字はNG(要スペース)

これは GNU Smalltalk に限らず、小数点と区別するため。


▼キーワードの「:」(コロン)の直後にアルファベットはNG(要スペース)

これは GNU Smalltalk のバージョンによるようです。


▼減算のマイナスの直後には要スペース

これも GNU Smalltalk クオリティ。他のまともな Smalltalk に慣れている人には要注意。

3-4!    "=> NG "
3- 4!   "=> OK "

▼数字の直後に d、e で始まるセレクタ(キーワード)はNG(要スペース)

1to:4do:[:i|]!    "=> NG "
1to:4 do:[:i|]!   "=> OK "

▼カーリーブレイス「{ }」での配列記述が可能

Squeak Smalltalk ではお馴染みのヤツ。意外…。つか、今の今まで知らなかったよ。orz

{3+4. 3- 4. 3*4. 3/4}!   "=> (7 -1 12 3/4 ) "


たとえば、古典的 Smalltalk では、

|x a|x:=#something. a:=Array with: x

としなければならないところを、

|x a|x:=#something. a:={x}

で、-10B(!)。


念のため、初学者向け“Smalltalk の落とし穴”情報として、Smalltalk では(GNU Smalltalk に限らず…)、要素が変数に関連づけされているオブジェクトや式の結果であるような(つまりリテラル式でない…)場合、よく見かける配列リテラル記述(#(...))は使えないので要注意です。

#('this' #is $a 10)        "=> OK ← 要素はすべてリテラル式だから… "
#(3+4 3*4 3@4)             "=> NG ← x@y もリテラル式ではないので注意… "
Array with: 3+4 with: 3*4  "=> OK "


関連して、リテラル式ではない nil、true、false(これらは Smalltalk では self、super、thisContext と同じ擬変数…)も、例外的にリテラル式のように扱われる傾向にあるようです(個人的にはこういう例外は嫌いなのですが、Squeak Smalltalk でもいつのまにかこうなっちゃいました)。

#(nil true false)  "=> OK ← 古典的には #nil #true #false というシンボルとして解釈 "

▼配列リテラル記述で、シンボルや配列を要素とするとき # を省略できない

上のを書いていて思いだした。これは GNU Smalltalk クオリティ。

#(a b c)      "=> NG。Squeak Smalltalk などでは #(#a #b #c) と解釈 "
#(#a #b #c)   "=> OK "

▼文字リテラル( $a など)の直後にはスペース不要

これは GNU Smalltalk に限らず。

#($a$b$c)size!   "=> 3 "

▼文字オブジェクトの出力に際しては文字列への変換は不要

$aasString display

とするところを

$adisplay

で、-9B 。


▼文字オブジェクトでは #asciiValue の変わりに #value が使える

GNU Smalltalk オンリー。

$aasciiValue!   "=> 97 "

とするところを

$avalue!        "=> 97 "

で、-5B 。


▼任意の文字列生成には Character value: n より n asCharacter を

Character value: 65

とするところを

65 asCharacter

で、-5B 。


▼文字列を文字の配列に

'abc'asArray   "=> #($a $b $c) "

とするところを、

#(),'abc'      "=> #($a $b $c) "

で、-3B 。


▼標準出力への改行(LF)出力

'
'display

とするところを、

stdout nl

で -1B 。

もちろん、直前に文字列リテラルを結合するなら、その文字列の最後に改行(LF)を追加すべき。


▼整数の出力には display を print で(あるいは displayNl を printNl)で代替可

4display

とするところを

4print

で、-2B 。


▼ #timesRepeat: より #to:do:

4timesRepeat:[]

とするところを、

1to:4 do:[:i|]

で -1B(ブロック変数〜 Ruby と違って省略は不可〜は無視)。ただし、範囲が変数の場合は旨味なし。