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? うーん。 説明的な単語を選ぶのかなあ。
みんなどうしてるんだろう。




