読者です 読者をやめる 読者になる 読者になる

僕のみた Smalltalk

Smalltalk 勉強会に行ってきた!!
http://www.smalltalk-users.jp/Home/gao-zhi/dai6kaismalltalkbenkyoukai

MVC の説明

MVC

モデルはビューを知らないけど
ビューはモデルに依存しまくり

クラシカルMVC

プラガブルMVC

VisualWorksでは

アプリケーションモデル
UIBuilder
UI の組立役
WindowSpec
なんというかこのまえのデブサミはてなが「MVAC」でやってる
って言ってたけど,それの事かなぁと思った.
懇親会で聞いてみたけど
「そのセッション聞いていないから何ともいえないけど
Smalltalk の世界では何十年も前に通った道だよ」
って教えていただいた.


ここから僕は何もわからないので入門として
色々教わった.

smalltalk 入門

全てオブジェクト
演算子とかも数字のオブジェクトのメソッドでしかない

構文は次のパターンしかない

オブジェクト メッセージ
オブジェクト メッセージ 1引数
オブジェクト メッセージ いっぱい引数

Hello,world
Transcript show: 'Hello,world!'

Transcript は簡単に言っちゃうとコンソールみたいなオブジェクト
そこに show: というメッセージを 'Hello,world!' と引数を付けて渡す

Transcript show: 3 printString

数字は文字列にするためのメッセージ printString を渡してから

処理の優先順位

引数無し
引数付き
の順で実行される

Transcript show: 3 = 3 printString

だと先に後ろの「3」に printString メッセージの送信をしてしまうので

Transcript show: (3 = 3) printString

と,明示的に () で処理の順番を指定する
演算子にも順番は無いので

3 + 4 * 7

は 49 になる
(3 + 4 を先にやって結果の 7 * 7 で49)

3 + (4 * 7)

で 31

変数の宣言
| hoge | 

これで変数の宣言.
複数宣言を同時に出来る

| hoge foo bar| 
変数への代入
hoge := [Transcript show: 'Hello,world! brank']

VisualWorks の場合は「:=」を使う
チンコ演算子 ktkr!!
ちなみに[]はブロッククロージャ

nil もオブジェクト
| hoge |
Transcript show: hoge printString

変数は最初はnilを差してる

クラス定義

クラスもオブジェクト
Smalltalk オジェクトに メッセージを送って生成する

Smalltalk defineClass: #Robot
        superclass: #{Core.Object}
        indexedType: #none
        private: false
        instanceVariableNames: 'dir'
        classInstanceVariableNames: ''
        imports: ''
        category: ''

Robot というクラスを作ってる.
インスタンス変数に dir を持たせてる

初期化
initialize
    dir := 0.
    ^self

変数の初期化してみた.
「^」はリターンで省略すると self が帰る.

new
    ^super new initialize

クラスメソッドのnew でメッセージ送ってるだけ

インスタンス変数へのアクセス

Smalltalk はすべてプライベート変数なので
インスタンスメソッドでアクセサを作る

dir
    ^dir
インスタンスメソッド

順番逆になっちゃったけど
インスタンスメソッドはこんな感じ

turn: anInteger
      dir := dir + anInteger

引数が必要なメソッドメソッド名の後ろに「:」を付ける
引数名は「aHoge」みたいにするのが慣例


で,こんな感じ

robot := Robot new.
robot turn: 90.
Transcript show: (robot dir = 90) printString
if もメッセージ呼出

true,false がそれぞれ
ifTrue: ifTrue:ifFalse ifFalse ifFalse:ifTrue
などのメソッドを持っている


True と False の ifTrue: と ifFalse: の実装みると面白いよって
教えてもらったので見てみた
True

ifTrue: alternativeBlock
       "Answer the value of alternativeBlock. This method is typically not
       invoked because ifTrue:/ifFalse: expressions are compiled in-line for
       literal blocks."

       ^alternativeBlock value

ifFalse: alternativeBlock
       "Since the condition is true, the value is the true alternative, which
       is nil. This method is typically not invoked because ifTrue:/ifFalse:
       expressions are compiled in-line for literal blocks."

       ^nil

true の ifTrue: は引数を評価して返す
ifFalse: は nil を返す
False

ifTrue: alternativeBlock
       "Since the condition is false, answer the value of the false
       alternative, which is nil. This method is typically not invoked
       because ifTrue:/ifFalse: expressions are compiled in-line for literal
       blocks."

       ^nil

ifFalse: alternativeBlock
       "Answer the value of alternativeBlock. This method is typically not
       invoked because ifTrue:/ifFalse: expressions are compiled in-line for
       literal blocks."

       ^alternativeBlock value

false は逆なだけ,
目から鱗的な感じ!!
オブジェクトへのメッセージ送信で if が実現出来るのは
こうやってみると当たり前だけど凄い感動した!!
Python の oneliner の式を繋げる処理を思い出した!!

ループ処理

数字にメッセージを送信する

1 to 5 do:[:index | Transcript show: index printString]

12345

とりあえずフェボナッチ
fib: anInteger
       | value1 value2 |
       value1 := 0.
       value2 := 1.
       0 to: anInteger do:
                       [:index |
                               | buf |
                               buf := value1.
                               Transcript show: value1 printString.
                               value1 := value1 + value2.
                               value2 := buf.
                               Transcript show: ','
                       ]

ベタに書いた.

感想

Smalltalk 凄い!!
構文がシンプルで全てオブジェクトに対するメッセージ送信で実現してるから
わかりやすい!!
勉強に良いなぁって思いました!!


また,smalltalk-users.jp の方々はすごく優しくて
疑問に思った事を質問しても嫌な顔せずにいっぱい教えてくれました!!
毎月開催してるので
みんな勉強しに Smalltalk 勉強会に行こう!!