Smalltalkベストプラクティス・パターンのtail
ケント・ベックのあれを後ろから読んでRubyでメモしたメモ。
このメモについて
ケント・ベックのSmalltalkベストプラクティス・パターン―シンプル・デザインへの宝石集 を後ろから読んだメモです。
8. 開発例
はじめに
ファイルmoney.rb
class Money def initialize(amount, currency) @amount = amount @currency = currency end attr_reader :amount attr_reader :currency def to_s "#{self.amount} #{self.currency}" end end
Workspaceはirbかな。
% irb --simple-prompt -r money >> puts Money.new(5, :USD) 5 USD
計算
class Money .... def add(money) self.class.new(self.amount + money.amount, self.currency) end alias + add end
うん。
% irb --simple-prompt -r money >> m1 = Money.new(5, :USD) >> m2 = Money.new(7, :USD) >> puts m1 + m2 12 USD
よし。
>> m2 = Money.new(7, :GBP) >> puts m1 + m2 12 USD
あれ??
MoneySum導入
class MoneySum def initialize(monies) @monies = monies end def to_s @monies.join(' + ') end end
money.addの変更
class Money def add(money) if self.currency == money.currency self.class.new(self.amount + money.amount, self.currency) else MoneySum.new([self, money]) end end end
も一度。
% irb --simple-prompt -r money >> m1 = Money.new(5, :USD) >> m2 = Money.new(7, :GBP) >> puts m1 + m2 5 USD + 7 GBP
うん。
統合
ImpostorにするためにDouble Dispatchでかっこよくする。
money.add_moneyの追加。
class Money ... def add_money(money) if self.currency == money.currency self.class.new(self.amount + money.amount, self.currency) else MoneySum.new([self, money]) end end def add(money) money.add_money(self) end end
money_sum.add, add_moneyの追加
class MoneySum ... attr_reader :monies def add_money(money) self.class.new(self.monies + [money]) end def add(money) money.add_money_sum(self) end alias + add end m1 = Money.new(5, :USD)
money + money_sum ができたっぽい。
% irb --simple-prompt -r money >> m1 = Money.new(5, :USD) >> m2 = Money.new(7, :GBP) >> puts m1 + (m2 + m1) 5 USD + 7 GBP + 5 USD
money_sum + moneyを定義します。
class Money ... def add_money_sum(money_sum) money_sum.add_money(self) end end
うまくいくかな。
% irb --simple-prompt -r money >> m1 = Money.new(5, :USD) >> m2 = Money.new(7, :GBP) >> puts m1 + m2 + m1 5 USD + 7 GBP + 5 USD
できた。
のこりはmoney_sum + money_sum。
class MoneySum ... def add_money_sum(money_sum) self.class.new(self.monies + money_sum.monies) end end
どかな。
% irb --simple-prompt -r money >> m1 = Money.new(5, :USD) >> m2 = Money.new(7, :GBP) >> puts (m1 + m2) + (m1 + m2) 7 GBP + 5 USD + 7 GBP + 5 USD
フォーマット
Interesting Return Value
明示的に値を返すように書くのはどんなとき?
Rubyだとどんなときだろう。
明示的に返さない場合、Smalltalkではレシーバが返され、 Rubyでは最後に評価した値が返されます。
Yourself
Cascadeないからなあ。
Cascade
Rubyにはない。
Simple Enumeration Parameter
- ブロックつきメソッドの、ブロックのパラメータの名前はどうしよう。
Smalltalkではdo:なので、パラメータの名前にeachをすすめているけど、 Rubyではeachなのよね。x, i, n? うーん。 説明的な単語を選ぶのかなあ。
みんなどうしてるんだろう。