Smalltalk風Ruby


https://twitter.com/technohippy/status/291697606638305280

とか言うことをつぶやきつつ考えたんですが、","に目を瞑ればRubyは1.9から key:val 形式のHashリテラルをキーワード引数っぽく使えるし、->{...} 形式のProcリテラルもあるしで、これってすでにほぼSmalltalkじゃないですか。

# Ruby
ret = ->{ 
    obj.message 'arg1', arg2:'arg2', arg3:'arg3'
}.call
"Smalltalk"
ret := [
    obj message: 'arg2' arg2: 'arg2' arg3: 'arg3'.
] value.

どっちがどっちか区別つかないレベル。

で、この際なので足りない部分を少し補ってRubyをもっとSmalltalkっぽく書けるようにと、小さなライブラリを作成しました。

https://github.com/technohippy/smalltalkable

require 'smalltalkable'

Object.subclass :Counter,
    instanceVariableNames: 'value step',
    classVariableNames: 'instanceCount',
    poolDictionaries: '', 
    category: 'Category-Name'

これを使うとクラス定義はこんなふうに書けます。

Counter.compile '
    initialize value, step:step
        @value = value
        @step = step'

メソッド定義はこんな感じ。文字列で渡すのがSmalltalk流。(嘘

counter = Counter.new 0, step:2

メッセージ送信はこう。

String.smalltalkize :rjust => [:rjustWidth, :padding]
'foo'.rjustWidth 10, padding:'*' #=> '*******foo' 

ちなみに既存のメソッドをSmalltalk風に再定義することもできます。

->{counter.value < 20}.while_true ->{
    (counter.value % 3 == 0).if_true ->{
        puts counter.value
    }
    counter.next
}

もちろん if や while もSmalltalkっぽく書けます。

$ sudo gem install smalltalkable

ということで、Smalltalkを愛してやまないけど仕事で已む無くRubyを使っている人はこのSmalltalkableで心の平穏を取り戻していただければと思います。