vieweditattachhistorytopchangessearchhelp

第20回


■SqueakではじめるSmalltalk入門   第20回


 本連載では、名前は知っていてもなかなか触れる機会のないSmalltalkについて、最近話題のSqueakシステムを使って紹介しています。今回は、残された“払い戻し”メソッドを定義してBankAccountを完成させます。

 メソッド#withdraw:は、基本的に#deposit:と逆、つまりパラメータの値を#balanceの返値から差し引く…という挙動を示せばよいので、メッセージパターン(あるいはメソッド名)を「deposit:」から「withdraw:」に、メソッド中の計算の「+」を「-」に置き換えさえすれば、とりあえずは動きます。

deposit: aNumber
  self balance: self balance + aNumber


     ↓

withdraw: aNumber
  self balance: self balance - aNumber


 ただこれだけではつまらないので、self balanceの結果が負にならないようにする制約を設けましょう。負にならないようにする方法はいくつか考えられます。ちょうどよい復習になるので、実際にコードをいろいろと考えてみてください。

 一番単純なのは、前述メソッドに、「self balanceが負なら、self balanceが0になるようにする」というメッセージ式を付け加える方法。既出のメッセージの組み合わせで記述できるはずです。

withdraw: aNumber
  self balance: self balance - aNumber.
  self balance < 0 ifTrue: [self balance: 0]


 メソッド本体は追加した式を含めて2行になります。Smalltalkでは式の区切りは「.」(ピリオド)であることを思い出してください。改行は原則としてスペース以上の意味を持ちません。1行目の終わりのピリオドを入れ忘れるとaNumberにselfというメッセージを送る式と解釈されてしまいます。さらに、前の行のselfに対する「balance: … ifTrue: …」というメッセージを送信する、2行全体がひとつのメッセージ式であると判断されてしまいます。もちろん、#balance:ifTrue:などというメソッドは定義されたことがないので、コンパイラが気を利かせてスペルチェッカを起動します。

[fig.A]1行目の終わりのピリオドを忘れたときの様子
Uploaded Image: 20a.png

 ピリオドや括弧の括り忘れは、このようにスペルチェッカの起動により気付かされることが多いです。スペルチェッカが、単純なスペルミスではなく、見慣れないメソッド名を指摘してきたらよく注意して勘違いや書き損じがないかコードをよく見直すべきでしょう。

 他にも、self balance - aNumberの結果を一時変数に束縛しておく手があります。

withdraw: aNumber
  | newBalance |
  newBalance _ self balance - aNumber.
  newBalance > 0
    ifTrue: [self balance: newBalance]
    ifFalse: [self balance: 0]


 Smalltalkでは、制御構造もメッセージ式で表現し、同時にそれは“文”ではなく“式”なので返値を持ちます。したがって、まったく同じ挙動を次のように書き換えることもできます。

withdraw: aNumber
  | newBalance |
  newBalance _ self balance - aNumber.
  self balance: (newBalance > 0 ifTrue: [newBalance] ifFalse: [0])


 レシーバとパラメータを比較して大きなほうを返値とする#max:というメソッドを知っていれば、一時変数も不要になり、式自体ももっとシンプルにできそうです。

withdraw: aNumber
  self balance: (self balance - aNumber max: 0)


 さあ、これでBankAccountは完成です。当初のスクリプトが期待通りに動作するか確かめてみましょう。

| account |
World findATranscript: nil.             "transcriptを開く"
account _ BankAccount new.              "a BankAccount作成"
account balance: 1000.                  "1000円預金"
Transcript cr; show: account balance.   "残高照会 => 1000 "
account withdraw: 600.                  "600円払戻"
Transcript cr; show: account balance.   "残高照会 => 400 "
account deposit: 60.                    "60円預入"
Transcript cr; show: account balance.   "残高照会 => 460 "
account withdraw: 700.                  "700円払戻"
Transcript cr; show: account balance.   "残高照会 => 0 "

このページを編集 (3531 bytes)


Congratulations! 以下の 1 ページから参照されています。

This page has been visited 906 times.