Smalltalk 勉強会に行ってきた!!
http://www.smalltalk-users.jp/Home/gao-zhi/dai6kaismalltalkbenkyoukai
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 := [Transcript show: 'Hello,world! brank']
VisualWorks の場合は「:=」を使う
チンコ演算子 ktkr!!
ちなみに[]はブロッククロージャ
クラス定義
クラスもオブジェクト
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 でメッセージ送ってるだけ
インスタンスメソッド
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: ',' ]
ベタに書いた.