Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

第15章 テスト任せとコンパイラ任せ #19

Merged
merged 11 commits into from
Nov 10, 2017
Merged

Conversation

at-grandpa
Copy link
Owner

@at-grandpa at-grandpa commented Nov 10, 2017

TODO

  • $5+10CHF=$10(レートが2:1の場合)
  • $5+$5=$10
  • $5+$5がMoneyを返す
  • Bank.reduce(Money)
  • Moneyを変換して換算を行う
  • Reduce(Bank, String)

@at-grandpa
Copy link
Owner Author

$5 + 10 CHFのテストを書けるところまできた。

@at-grandpa
Copy link
Owner Author

コンパイルエラーが起きると本書には書いてあったが、コンパイルは通って、テストが落ちる形になってしまった。

 crystal spec' <

.........F

Failures:

  1) MoneyPackage testMixedAddition() 異なる通貨の足し算ができること
     Failure/Error: result.should eq Money.dollar(10)

       Expected: #<MoneyPackage::Money:0x1088b6800 @amount=10, @currency="USD">
            got: #<MoneyPackage::Money:0x1088b6820 @amount=15, @currency="USD">

     # spec/money_package_spec.cr:79

Finished in 1.5 milliseconds
10 examples, 1 failures, 0 errors, 0 pending

Failed examples:

crystal spec spec/money_package_spec.cr:73 # MoneyPackage testMixedAddition() 異なる通貨の足し算ができること

なぜコンパイルが通ったのか。

@at-grandpa
Copy link
Owner Author

本書では、

以前の章で Money から Expression への一般化を行ったときに、多くの事柄を先送りにしてしまった。

とある。13章でExpressionの一般化を行ったところだ。

@at-grandpa
Copy link
Owner Author

しかし、ちょっとパッとわからなかったので飛ばす。次にステップで合流するし。これは言語依存かな。

@at-grandpa
Copy link
Owner Author

着実に進めていく。

@at-grandpa
Copy link
Owner Author

テストが落ちる。

 crystal spec' <

.........F

Failures:

  1) MoneyPackage testMixedAddition() 異なる通貨の足し算ができること
     Failure/Error: result.should eq Money.dollar(10)

       Expected: #<MoneyPackage::Money:0x10d342800 @amount=10, @currency="USD">
            got: #<MoneyPackage::Money:0x10d342820 @amount=15, @currency="USD">

     # spec/money_package_spec.cr:79

Finished in 1.46 milliseconds
10 examples, 1 failures, 0 errors, 0 pending

Failed examples:

crystal spec spec/money_package_spec.cr:73 # MoneyPackage testMixedAddition() 異なる通貨の足し算ができること

@at-grandpa
Copy link
Owner Author

Sumでのamount計算の時に、換算されていない。

@at-grandpa
Copy link
Owner Author

Bankを通して、augendとaddendの両方を換算すればokなはず。それぞれで通貨が異なるので。

@at-grandpa
Copy link
Owner Author

なんかreduceがいろいろあるけど、これらは「換算」を行っている。

@at-grandpa
Copy link
Owner Author

グリーン。

 crystal spec' <

..........

Finished in 1.18 milliseconds
10 examples, 0 failures, 0 errors, 0 pending

@at-grandpa
Copy link
Owner Author

at-grandpa commented Nov 10, 2017

ここからは Money を Expression に せっせと置き換えていく段階だ。

Expressionは12章のここで出てきている。

なので、計算処理は全てExpressionで行い、最終換算で出来上がるものだけがMoneyということになる。

@at-grandpa
Copy link
Owner Author

依存の終端から修正を始める。

@at-grandpa
Copy link
Owner Author

at-grandpa commented Nov 10, 2017

グリーン。

SumにはCompositeパターンが良さそうに思うが、まだそこまではしない。二つ以上の引数を取るようになったら考える。

@at-grandpa
Copy link
Owner Author

at-grandpa commented Nov 10, 2017

本書では、fiveBucksをExpressionにするとコンパイルエラーが起きると書いてあるが、起きない。

@at-grandpa
Copy link
Owner Author

本書では、fiveBucksをExpressionにすると、

真面目なコンパイラが Expression に plus メソッドが定義されていないと教えてくれる。

とある。もしかしたら、crystalの場合は、型はMoneyだと判定され、そこにplusがあるからなのかもしれない。

@at-grandpa
Copy link
Owner Author

テストが通る。

 crystal spec' <

..........

Finished in 1.38 milliseconds
10 examples, 0 failures, 0 errors, 0 pending

@at-grandpa
Copy link
Owner Author

これはおそらく、言語仕様。crystalのメソッド探索チェーンの仕様だと、たしかにplusメソッドは見つかってしまう。javaは「Expression型はExpressionで定義されたメソッドしか見えない」っぽいが、crystalでの今回のExpressionの実装はmoduleなので、includeするだけ。メソッドを付与するだけ。ExpressionをincludeしたMoneyをnewすれば、Expressionをincludeしていることは事実だし、plusメソッドを持っているのも事実。何ら間違いではない。

とりあえず進む。

@at-grandpa
Copy link
Owner Author

コンパイルエラー。

 crystal spec' <

Error in src/money_package/expression.cr:3: abstract `def MoneyPackage::Expression#plus(addend : Expression)` must be implemented by MoneyPackage::Sum

    abstract def plus(addend : Expression) : Expression
                 ^~~~

Sumにplusがないよ。本書に近づいてきた。

@at-grandpa
Copy link
Owner Author

at-grandpa commented Nov 10, 2017

グリーンになったが、空実装があるのでTODOリストに追加する。

@at-grandpa
Copy link
Owner Author

at-grandpa commented Nov 10, 2017

TODO

  • $5+10CHF=$10(レートが2:1の場合)
  • $5+$5=$10
  • $5+$5がMoneyを返す
  • Bank.reduce(Money)
  • Moneyを変換して換算を行う
  • Reduce(Bank, String)
  • Sum.plus
  • Expression.times

@at-grandpa
Copy link
Owner Author

MoneyからExpressionへの実装を一般化できそうだ。

@at-grandpa
Copy link
Owner Author

振り返り。

  • こうなったら良いというテストを書き、次にまず一歩で動かせるところまでそのテストを少し後退させた
  • 一般化(より抽象度の高い型で宣言する)作業を、末端から開始して頂点(テストケース)まで到達させた
  • 変更の際にコンパイラに従い(fiveBucks変数のExpression型への変更)、変更の連鎖を一つずつ仕留めた(Expressionインターフェースへのplusメソッドの追加等)

@at-grandpa
Copy link
Owner Author

15章終了。

@at-grandpa at-grandpa merged commit d2b962a into master Nov 10, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants