@k2works/claude-code-booster 3.0.0 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/assets/docs/article/functional-desgin-ppp/all/01-immutability-and-data-transformation.md +475 -0
- package/lib/assets/docs/article/functional-desgin-ppp/all/02-function-composition.md +519 -0
- package/lib/assets/docs/article/functional-desgin-ppp/all/03-polymorphism.md +537 -0
- package/lib/assets/docs/article/functional-desgin-ppp/all/04-data-validation.md +300 -0
- package/lib/assets/docs/article/functional-desgin-ppp/all/05-property-based-testing.md +320 -0
- package/lib/assets/docs/article/functional-desgin-ppp/all/06-tdd-and-functional.md +498 -0
- package/lib/assets/docs/article/functional-desgin-ppp/all/07-composite-pattern.md +298 -0
- package/lib/assets/docs/article/functional-desgin-ppp/all/08-decorator-pattern.md +291 -0
- package/lib/assets/docs/article/functional-desgin-ppp/all/09-adapter-pattern.md +336 -0
- package/lib/assets/docs/article/functional-desgin-ppp/all/10-strategy-pattern.md +303 -0
- package/lib/assets/docs/article/functional-desgin-ppp/all/11-command-pattern.md +286 -0
- package/lib/assets/docs/article/functional-desgin-ppp/all/12-visitor-pattern.md +322 -0
- package/lib/assets/docs/article/functional-desgin-ppp/all/13-abstract-factory-pattern.md +319 -0
- package/lib/assets/docs/article/functional-desgin-ppp/all/14-abstract-server-pattern.md +365 -0
- package/lib/assets/docs/article/functional-desgin-ppp/all/15-gossiping-bus-drivers.md +156 -0
- package/lib/assets/docs/article/functional-desgin-ppp/all/16-payroll-system.md +178 -0
- package/lib/assets/docs/article/functional-desgin-ppp/all/17-video-rental-system.md +312 -0
- package/lib/assets/docs/article/functional-desgin-ppp/all/18-concurrency-system.md +287 -0
- package/lib/assets/docs/article/functional-desgin-ppp/all/19-wa-tor-simulation.md +286 -0
- package/lib/assets/docs/article/functional-desgin-ppp/all/20-pattern-interactions.md +274 -0
- package/lib/assets/docs/article/functional-desgin-ppp/all/21-best-practices.md +294 -0
- package/lib/assets/docs/article/functional-desgin-ppp/all/22-oo-to-fp-migration.md +337 -0
- package/lib/assets/docs/article/functional-desgin-ppp/all/index.md +388 -0
- package/lib/assets/docs/article/functional-desgin-ppp/clojure/01-immutability-and-data-transformation.md +271 -0
- package/lib/assets/docs/article/functional-desgin-ppp/clojure/02-function-composition.md +380 -0
- package/lib/assets/docs/article/functional-desgin-ppp/clojure/03-polymorphism.md +384 -0
- package/lib/assets/docs/article/functional-desgin-ppp/clojure/04-clojure-spec.md +350 -0
- package/lib/assets/docs/article/functional-desgin-ppp/clojure/05-property-based-testing.md +352 -0
- package/lib/assets/docs/article/functional-desgin-ppp/clojure/06-tdd-in-functional.md +383 -0
- package/lib/assets/docs/article/functional-desgin-ppp/clojure/07-composite-pattern.md +529 -0
- package/lib/assets/docs/article/functional-desgin-ppp/clojure/08-decorator-pattern.md +395 -0
- package/lib/assets/docs/article/functional-desgin-ppp/clojure/09-adapter-pattern.md +399 -0
- package/lib/assets/docs/article/functional-desgin-ppp/clojure/10-strategy-pattern.md +485 -0
- package/lib/assets/docs/article/functional-desgin-ppp/clojure/11-command-pattern.md +566 -0
- package/lib/assets/docs/article/functional-desgin-ppp/clojure/12-visitor-pattern.md +567 -0
- package/lib/assets/docs/article/functional-desgin-ppp/clojure/13-abstract-factory-pattern.md +475 -0
- package/lib/assets/docs/article/functional-desgin-ppp/clojure/14-abstract-server-pattern.md +462 -0
- package/lib/assets/docs/article/functional-desgin-ppp/clojure/15-gossiping-bus-drivers.md +323 -0
- package/lib/assets/docs/article/functional-desgin-ppp/clojure/16-payroll-system.md +401 -0
- package/lib/assets/docs/article/functional-desgin-ppp/clojure/17-video-rental-system.md +450 -0
- package/lib/assets/docs/article/functional-desgin-ppp/clojure/18-concurrency-system.md +475 -0
- package/lib/assets/docs/article/functional-desgin-ppp/clojure/19-wator-simulation.md +739 -0
- package/lib/assets/docs/article/functional-desgin-ppp/clojure/20-pattern-interactions.md +562 -0
- package/lib/assets/docs/article/functional-desgin-ppp/clojure/21-best-practices.md +506 -0
- package/lib/assets/docs/article/functional-desgin-ppp/clojure/22-oo-to-fp-migration.md +526 -0
- package/lib/assets/docs/article/functional-desgin-ppp/clojure/index.md +197 -0
- package/lib/assets/docs/article/functional-desgin-ppp/elixir/01-immutability-and-data-transformation.md +381 -0
- package/lib/assets/docs/article/functional-desgin-ppp/elixir/02-function-composition.md +374 -0
- package/lib/assets/docs/article/functional-desgin-ppp/elixir/03-polymorphism.md +375 -0
- package/lib/assets/docs/article/functional-desgin-ppp/elixir/04-data-validation.md +195 -0
- package/lib/assets/docs/article/functional-desgin-ppp/elixir/05-property-based-testing.md +268 -0
- package/lib/assets/docs/article/functional-desgin-ppp/elixir/06-tdd-and-fp.md +294 -0
- package/lib/assets/docs/article/functional-desgin-ppp/elixir/07-effects-and-pure-functions.md +164 -0
- package/lib/assets/docs/article/functional-desgin-ppp/elixir/08-error-handling-strategies.md +168 -0
- package/lib/assets/docs/article/functional-desgin-ppp/elixir/09-io-and-external-systems.md +254 -0
- package/lib/assets/docs/article/functional-desgin-ppp/elixir/10-concurrency-patterns.md +269 -0
- package/lib/assets/docs/article/functional-desgin-ppp/elixir/11-command-pattern.md +148 -0
- package/lib/assets/docs/article/functional-desgin-ppp/elixir/12-visitor-pattern.md +176 -0
- package/lib/assets/docs/article/functional-desgin-ppp/elixir/13-abstract-factory-pattern.md +604 -0
- package/lib/assets/docs/article/functional-desgin-ppp/elixir/14-abstract-server-pattern.md +729 -0
- package/lib/assets/docs/article/functional-desgin-ppp/elixir/15-gossiping-bus-drivers.md +291 -0
- package/lib/assets/docs/article/functional-desgin-ppp/elixir/16-payroll-system.md +420 -0
- package/lib/assets/docs/article/functional-desgin-ppp/elixir/17-video-rental-system.md +319 -0
- package/lib/assets/docs/article/functional-desgin-ppp/elixir/18-concurrency-system.md +466 -0
- package/lib/assets/docs/article/functional-desgin-ppp/elixir/19-wator-simulation.md +523 -0
- package/lib/assets/docs/article/functional-desgin-ppp/elixir/20-pattern-interactions.md +287 -0
- package/lib/assets/docs/article/functional-desgin-ppp/elixir/21-best-practices.md +340 -0
- package/lib/assets/docs/article/functional-desgin-ppp/elixir/22-oo-to-fp-migration.md +395 -0
- package/lib/assets/docs/article/functional-desgin-ppp/elixir/index.md +204 -0
- package/lib/assets/docs/article/functional-desgin-ppp/fsharp/01-immutability-and-data-transformation.md +382 -0
- package/lib/assets/docs/article/functional-desgin-ppp/fsharp/02-function-composition.md +452 -0
- package/lib/assets/docs/article/functional-desgin-ppp/fsharp/03-polymorphism.md +495 -0
- package/lib/assets/docs/article/functional-desgin-ppp/fsharp/04-data-validation.md +416 -0
- package/lib/assets/docs/article/functional-desgin-ppp/fsharp/05-property-based-testing.md +382 -0
- package/lib/assets/docs/article/functional-desgin-ppp/fsharp/06-tdd-functional.md +687 -0
- package/lib/assets/docs/article/functional-desgin-ppp/fsharp/07-composite-pattern.md +442 -0
- package/lib/assets/docs/article/functional-desgin-ppp/fsharp/08-decorator-pattern.md +479 -0
- package/lib/assets/docs/article/functional-desgin-ppp/fsharp/09-adapter-pattern.md +479 -0
- package/lib/assets/docs/article/functional-desgin-ppp/fsharp/10-strategy-pattern.md +427 -0
- package/lib/assets/docs/article/functional-desgin-ppp/fsharp/11-command-pattern.md +428 -0
- package/lib/assets/docs/article/functional-desgin-ppp/fsharp/12-visitor-pattern.md +339 -0
- package/lib/assets/docs/article/functional-desgin-ppp/fsharp/13-abstract-factory-pattern.md +309 -0
- package/lib/assets/docs/article/functional-desgin-ppp/fsharp/14-abstract-server-pattern.md +596 -0
- package/lib/assets/docs/article/functional-desgin-ppp/fsharp/15-gossiping-bus-drivers.md +353 -0
- package/lib/assets/docs/article/functional-desgin-ppp/fsharp/16-payroll-system.md +350 -0
- package/lib/assets/docs/article/functional-desgin-ppp/fsharp/17-video-rental-system.md +412 -0
- package/lib/assets/docs/article/functional-desgin-ppp/fsharp/18-concurrency-system.md +367 -0
- package/lib/assets/docs/article/functional-desgin-ppp/fsharp/19-wator-simulation.md +401 -0
- package/lib/assets/docs/article/functional-desgin-ppp/fsharp/20-pattern-interactions.md +291 -0
- package/lib/assets/docs/article/functional-desgin-ppp/fsharp/21-best-practices.md +320 -0
- package/lib/assets/docs/article/functional-desgin-ppp/fsharp/22-oo-to-fp-migration.md +322 -0
- package/lib/assets/docs/article/functional-desgin-ppp/fsharp/index.md +230 -0
- package/lib/assets/docs/article/functional-desgin-ppp/haskell/01-immutability-and-data-transformation.md +298 -0
- package/lib/assets/docs/article/functional-desgin-ppp/haskell/02-function-composition.md +304 -0
- package/lib/assets/docs/article/functional-desgin-ppp/haskell/03-polymorphism.md +362 -0
- package/lib/assets/docs/article/functional-desgin-ppp/haskell/04-data-validation.md +257 -0
- package/lib/assets/docs/article/functional-desgin-ppp/haskell/05-property-based-testing.md +254 -0
- package/lib/assets/docs/article/functional-desgin-ppp/haskell/06-tdd-functional.md +283 -0
- package/lib/assets/docs/article/functional-desgin-ppp/haskell/07-composite-pattern.md +395 -0
- package/lib/assets/docs/article/functional-desgin-ppp/haskell/08-decorator-pattern.md +319 -0
- package/lib/assets/docs/article/functional-desgin-ppp/haskell/09-adapter-pattern.md +382 -0
- package/lib/assets/docs/article/functional-desgin-ppp/haskell/10-strategy-pattern.md +287 -0
- package/lib/assets/docs/article/functional-desgin-ppp/haskell/11-command-pattern.md +303 -0
- package/lib/assets/docs/article/functional-desgin-ppp/haskell/12-visitor-pattern.md +326 -0
- package/lib/assets/docs/article/functional-desgin-ppp/haskell/13-abstract-factory-pattern.md +332 -0
- package/lib/assets/docs/article/functional-desgin-ppp/haskell/14-abstract-server-pattern.md +379 -0
- package/lib/assets/docs/article/functional-desgin-ppp/haskell/15-gossiping-bus-drivers.md +175 -0
- package/lib/assets/docs/article/functional-desgin-ppp/haskell/16-payroll-system.md +219 -0
- package/lib/assets/docs/article/functional-desgin-ppp/haskell/17-video-rental-system.md +244 -0
- package/lib/assets/docs/article/functional-desgin-ppp/haskell/18-concurrency-system.md +363 -0
- package/lib/assets/docs/article/functional-desgin-ppp/haskell/19-wator-simulation.md +438 -0
- package/lib/assets/docs/article/functional-desgin-ppp/haskell/20-pattern-interactions.md +323 -0
- package/lib/assets/docs/article/functional-desgin-ppp/haskell/21-best-practices.md +403 -0
- package/lib/assets/docs/article/functional-desgin-ppp/haskell/22-oo-to-fp-migration.md +469 -0
- package/lib/assets/docs/article/functional-desgin-ppp/haskell/index.md +174 -0
- package/lib/assets/docs/article/functional-desgin-ppp/index.md +90 -0
- package/lib/assets/docs/article/functional-desgin-ppp/rust/01-immutability-and-data-transformation.md +448 -0
- package/lib/assets/docs/article/functional-desgin-ppp/rust/02-function-composition.md +463 -0
- package/lib/assets/docs/article/functional-desgin-ppp/rust/03-polymorphism.md +425 -0
- package/lib/assets/docs/article/functional-desgin-ppp/rust/04-data-validation.md +273 -0
- package/lib/assets/docs/article/functional-desgin-ppp/rust/05-property-based-testing.md +247 -0
- package/lib/assets/docs/article/functional-desgin-ppp/rust/06-tdd-and-functional.md +841 -0
- package/lib/assets/docs/article/functional-desgin-ppp/rust/07-composite-pattern.md +384 -0
- package/lib/assets/docs/article/functional-desgin-ppp/rust/08-decorator-pattern.md +383 -0
- package/lib/assets/docs/article/functional-desgin-ppp/rust/09-adapter-pattern.md +339 -0
- package/lib/assets/docs/article/functional-desgin-ppp/rust/10-strategy-pattern.md +331 -0
- package/lib/assets/docs/article/functional-desgin-ppp/rust/11-command-pattern.md +356 -0
- package/lib/assets/docs/article/functional-desgin-ppp/rust/12-visitor-pattern.md +379 -0
- package/lib/assets/docs/article/functional-desgin-ppp/rust/13-abstract-factory-pattern.md +361 -0
- package/lib/assets/docs/article/functional-desgin-ppp/rust/14-abstract-server-pattern.md +392 -0
- package/lib/assets/docs/article/functional-desgin-ppp/rust/15-gossiping-bus-drivers.md +300 -0
- package/lib/assets/docs/article/functional-desgin-ppp/rust/16-payroll-system.md +297 -0
- package/lib/assets/docs/article/functional-desgin-ppp/rust/17-video-rental-system.md +304 -0
- package/lib/assets/docs/article/functional-desgin-ppp/rust/18-concurrency-system.md +315 -0
- package/lib/assets/docs/article/functional-desgin-ppp/rust/19-wator-simulation.md +311 -0
- package/lib/assets/docs/article/functional-desgin-ppp/rust/20-pattern-interactions.md +304 -0
- package/lib/assets/docs/article/functional-desgin-ppp/rust/21-best-practices.md +336 -0
- package/lib/assets/docs/article/functional-desgin-ppp/rust/22-oo-to-fp-migration.md +349 -0
- package/lib/assets/docs/article/functional-desgin-ppp/rust/index.md +199 -0
- package/lib/assets/docs/article/functional-desgin-ppp/scala/01-immutability-and-data-transformation.md +326 -0
- package/lib/assets/docs/article/functional-desgin-ppp/scala/02-function-composition.md +348 -0
- package/lib/assets/docs/article/functional-desgin-ppp/scala/03-polymorphism.md +357 -0
- package/lib/assets/docs/article/functional-desgin-ppp/scala/04-data-validation.md +364 -0
- package/lib/assets/docs/article/functional-desgin-ppp/scala/05-property-based-testing.md +515 -0
- package/lib/assets/docs/article/functional-desgin-ppp/scala/06-tdd-functional.md +557 -0
- package/lib/assets/docs/article/functional-desgin-ppp/scala/07-composite-pattern.md +363 -0
- package/lib/assets/docs/article/functional-desgin-ppp/scala/08-decorator-pattern.md +327 -0
- package/lib/assets/docs/article/functional-desgin-ppp/scala/09-adapter-pattern.md +517 -0
- package/lib/assets/docs/article/functional-desgin-ppp/scala/10-strategy-pattern.md +441 -0
- package/lib/assets/docs/article/functional-desgin-ppp/scala/11-command-pattern.md +407 -0
- package/lib/assets/docs/article/functional-desgin-ppp/scala/12-visitor-pattern.md +379 -0
- package/lib/assets/docs/article/functional-desgin-ppp/scala/13-abstract-factory-pattern.md +398 -0
- package/lib/assets/docs/article/functional-desgin-ppp/scala/14-abstract-server-pattern.md +476 -0
- package/lib/assets/docs/article/functional-desgin-ppp/scala/15-gossiping-bus-drivers.md +389 -0
- package/lib/assets/docs/article/functional-desgin-ppp/scala/16-payroll-system.md +342 -0
- package/lib/assets/docs/article/functional-desgin-ppp/scala/17-video-rental-system.md +324 -0
- package/lib/assets/docs/article/functional-desgin-ppp/scala/18-concurrency-system.md +730 -0
- package/lib/assets/docs/article/functional-desgin-ppp/scala/19-wator-simulation.md +624 -0
- package/lib/assets/docs/article/functional-desgin-ppp/scala/20-pattern-interactions.md +512 -0
- package/lib/assets/docs/article/functional-desgin-ppp/scala/21-best-practices.md +427 -0
- package/lib/assets/docs/article/functional-desgin-ppp/scala/22-oo-to-fp-migration.md +682 -0
- package/lib/assets/docs/article/functional-desgin-ppp/scala/index.md +199 -0
- package/lib/assets/docs/article/getting-start-tdd/clojure/01-todo-list-and-first-test.md +166 -0
- package/lib/assets/docs/article/getting-start-tdd/clojure/02-fake-it-and-triangulation.md +162 -0
- package/lib/assets/docs/article/getting-start-tdd/clojure/03-obvious-implementation-and-refactoring.md +135 -0
- package/lib/assets/docs/article/getting-start-tdd/clojure/04-version-control-and-conventional-commits.md +88 -0
- package/lib/assets/docs/article/getting-start-tdd/clojure/05-package-management-and-static-analysis.md +299 -0
- package/lib/assets/docs/article/getting-start-tdd/clojure/06-task-runner-and-ci-cd.md +241 -0
- package/lib/assets/docs/article/getting-start-tdd/clojure/07-protocols-and-records.md +131 -0
- package/lib/assets/docs/article/getting-start-tdd/clojure/08-multimethods-and-design-patterns.md +130 -0
- package/lib/assets/docs/article/getting-start-tdd/clojure/09-namespaces-and-module-design.md +127 -0
- package/lib/assets/docs/article/getting-start-tdd/clojure/10-higher-order-functions-and-composition.md +114 -0
- package/lib/assets/docs/article/getting-start-tdd/clojure/11-persistent-data-and-pipeline.md +138 -0
- package/lib/assets/docs/article/getting-start-tdd/clojure/12-error-handling-and-spec.md +161 -0
- package/lib/assets/docs/article/getting-start-tdd/clojure/index.md +65 -0
- package/lib/assets/docs/article/getting-start-tdd/csharp/chapter01.md +232 -0
- package/lib/assets/docs/article/getting-start-tdd/csharp/chapter02.md +244 -0
- package/lib/assets/docs/article/getting-start-tdd/csharp/chapter03.md +202 -0
- package/lib/assets/docs/article/getting-start-tdd/csharp/chapter04.md +92 -0
- package/lib/assets/docs/article/getting-start-tdd/csharp/chapter05.md +256 -0
- package/lib/assets/docs/article/getting-start-tdd/csharp/chapter06.md +195 -0
- package/lib/assets/docs/article/getting-start-tdd/csharp/chapter07.md +214 -0
- package/lib/assets/docs/article/getting-start-tdd/csharp/chapter08.md +249 -0
- package/lib/assets/docs/article/getting-start-tdd/csharp/chapter09.md +174 -0
- package/lib/assets/docs/article/getting-start-tdd/csharp/chapter10.md +166 -0
- package/lib/assets/docs/article/getting-start-tdd/csharp/chapter11.md +192 -0
- package/lib/assets/docs/article/getting-start-tdd/csharp/chapter12.md +211 -0
- package/lib/assets/docs/article/getting-start-tdd/csharp/index.md +83 -0
- package/lib/assets/docs/article/getting-start-tdd/elixir/01-todo-list-and-first-test.md +87 -0
- package/lib/assets/docs/article/getting-start-tdd/elixir/02-fake-it-and-triangulation.md +95 -0
- package/lib/assets/docs/article/getting-start-tdd/elixir/03-obvious-implementation-and-refactoring.md +109 -0
- package/lib/assets/docs/article/getting-start-tdd/elixir/04-version-control-and-conventional-commits.md +96 -0
- package/lib/assets/docs/article/getting-start-tdd/elixir/05-package-management-and-static-analysis.md +88 -0
- package/lib/assets/docs/article/getting-start-tdd/elixir/06-task-runner-and-ci-cd.md +71 -0
- package/lib/assets/docs/article/getting-start-tdd/elixir/07-structs-and-protocols.md +110 -0
- package/lib/assets/docs/article/getting-start-tdd/elixir/08-pattern-matching-and-guards.md +108 -0
- package/lib/assets/docs/article/getting-start-tdd/elixir/09-module-design-and-behaviours.md +104 -0
- package/lib/assets/docs/article/getting-start-tdd/elixir/10-higher-order-functions-and-pipeline.md +178 -0
- package/lib/assets/docs/article/getting-start-tdd/elixir/11-stream-and-lazy-evaluation.md +142 -0
- package/lib/assets/docs/article/getting-start-tdd/elixir/12-error-handling-and-with.md +145 -0
- package/lib/assets/docs/article/getting-start-tdd/elixir/index.md +35 -0
- package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter01.md +202 -0
- package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter02.md +246 -0
- package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter03.md +218 -0
- package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter04.md +179 -0
- package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter05.md +267 -0
- package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter06.md +190 -0
- package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter07.md +161 -0
- package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter08.md +175 -0
- package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter09.md +222 -0
- package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter10.md +189 -0
- package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter11.md +212 -0
- package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter12.md +215 -0
- package/lib/assets/docs/article/getting-start-tdd/fsharp/index.md +71 -0
- package/lib/assets/docs/article/getting-start-tdd/go/01-todo-list-and-first-test.md +213 -0
- package/lib/assets/docs/article/getting-start-tdd/go/02-fake-it-and-triangulation.md +302 -0
- package/lib/assets/docs/article/getting-start-tdd/go/03-obvious-implementation-and-refactoring.md +339 -0
- package/lib/assets/docs/article/getting-start-tdd/go/04-version-control-and-conventional-commits.md +112 -0
- package/lib/assets/docs/article/getting-start-tdd/go/05-package-management-and-static-analysis.md +272 -0
- package/lib/assets/docs/article/getting-start-tdd/go/06-task-runner-and-ci-cd.md +233 -0
- package/lib/assets/docs/article/getting-start-tdd/go/07-encapsulation-and-polymorphism.md +394 -0
- package/lib/assets/docs/article/getting-start-tdd/go/08-design-patterns.md +422 -0
- package/lib/assets/docs/article/getting-start-tdd/go/09-solid-principles-and-module-design.md +400 -0
- package/lib/assets/docs/article/getting-start-tdd/go/10-higher-order-functions-and-composition.md +226 -0
- package/lib/assets/docs/article/getting-start-tdd/go/11-immutable-data-and-pipeline.md +296 -0
- package/lib/assets/docs/article/getting-start-tdd/go/12-error-handling-and-type-safety.md +411 -0
- package/lib/assets/docs/article/getting-start-tdd/go/index.md +83 -0
- package/lib/assets/docs/article/getting-start-tdd/haskell/01-todo-list-and-first-test.md +279 -0
- package/lib/assets/docs/article/getting-start-tdd/haskell/02-fake-it-and-triangulation.md +337 -0
- package/lib/assets/docs/article/getting-start-tdd/haskell/03-obvious-implementation-and-refactoring.md +257 -0
- package/lib/assets/docs/article/getting-start-tdd/haskell/04-version-control-and-conventional-commits.md +182 -0
- package/lib/assets/docs/article/getting-start-tdd/haskell/05-package-management-and-static-analysis.md +313 -0
- package/lib/assets/docs/article/getting-start-tdd/haskell/06-task-runner-and-ci-cd.md +309 -0
- package/lib/assets/docs/article/getting-start-tdd/haskell/07-algebraic-data-types-and-type-classes.md +412 -0
- package/lib/assets/docs/article/getting-start-tdd/haskell/08-pattern-matching-and-guards.md +390 -0
- package/lib/assets/docs/article/getting-start-tdd/haskell/09-module-design-and-smart-constructors.md +461 -0
- package/lib/assets/docs/article/getting-start-tdd/haskell/10-higher-order-functions-and-currying.md +434 -0
- package/lib/assets/docs/article/getting-start-tdd/haskell/11-function-composition-and-point-free.md +392 -0
- package/lib/assets/docs/article/getting-start-tdd/haskell/12-monad-and-error-handling.md +631 -0
- package/lib/assets/docs/article/getting-start-tdd/haskell/index.md +49 -0
- package/lib/assets/docs/article/getting-start-tdd/index.md +93 -0
- package/lib/assets/docs/article/getting-start-tdd/integration/01-language-overview.md +375 -0
- package/lib/assets/docs/article/getting-start-tdd/integration/02-test-framework-comparison.md +349 -0
- package/lib/assets/docs/article/getting-start-tdd/integration/03-tdd-pattern-comparison.md +445 -0
- package/lib/assets/docs/article/getting-start-tdd/integration/04-type-system-comparison.md +405 -0
- package/lib/assets/docs/article/getting-start-tdd/integration/05-dev-environment-comparison.md +330 -0
- package/lib/assets/docs/article/getting-start-tdd/integration/06-learning-roadmap.md +274 -0
- package/lib/assets/docs/article/getting-start-tdd/integration/index.md +69 -0
- package/lib/assets/docs/article/getting-start-tdd/java/01-todo-list-and-first-test.md +234 -0
- package/lib/assets/docs/article/getting-start-tdd/java/02-fake-it-and-triangulation.md +261 -0
- package/lib/assets/docs/article/getting-start-tdd/java/03-obvious-implementation-and-refactoring.md +185 -0
- package/lib/assets/docs/article/getting-start-tdd/java/04-version-control-and-conventional-commits.md +115 -0
- package/lib/assets/docs/article/getting-start-tdd/java/05-package-management-and-static-analysis.md +382 -0
- package/lib/assets/docs/article/getting-start-tdd/java/06-task-runner-and-ci-cd.md +272 -0
- package/lib/assets/docs/article/getting-start-tdd/java/07-encapsulation-and-polymorphism.md +626 -0
- package/lib/assets/docs/article/getting-start-tdd/java/08-design-patterns.md +393 -0
- package/lib/assets/docs/article/getting-start-tdd/java/09-solid-principles-and-module-design.md +310 -0
- package/lib/assets/docs/article/getting-start-tdd/java/10-higher-order-functions-and-composition.md +188 -0
- package/lib/assets/docs/article/getting-start-tdd/java/11-immutable-data-and-pipeline.md +167 -0
- package/lib/assets/docs/article/getting-start-tdd/java/12-error-handling-and-type-safety.md +205 -0
- package/lib/assets/docs/article/getting-start-tdd/java/index.md +61 -0
- package/lib/assets/docs/article/getting-start-tdd/node/01-todo-list-and-first-test.md +244 -0
- package/lib/assets/docs/article/getting-start-tdd/node/02-fake-it-and-triangulation.md +262 -0
- package/lib/assets/docs/article/getting-start-tdd/node/03-obvious-implementation-and-refactoring.md +169 -0
- package/lib/assets/docs/article/getting-start-tdd/node/04-version-control-and-conventional-commits.md +112 -0
- package/lib/assets/docs/article/getting-start-tdd/node/05-package-management-and-static-analysis.md +314 -0
- package/lib/assets/docs/article/getting-start-tdd/node/06-task-runner-and-ci-cd.md +235 -0
- package/lib/assets/docs/article/getting-start-tdd/node/07-encapsulation-and-polymorphism.md +327 -0
- package/lib/assets/docs/article/getting-start-tdd/node/08-design-patterns.md +322 -0
- package/lib/assets/docs/article/getting-start-tdd/node/09-solid-principles-and-module-design.md +285 -0
- package/lib/assets/docs/article/getting-start-tdd/node/10-higher-order-functions-and-composition.md +199 -0
- package/lib/assets/docs/article/getting-start-tdd/node/11-immutable-data-and-pipeline.md +207 -0
- package/lib/assets/docs/article/getting-start-tdd/node/12-error-handling-and-type-safety.md +295 -0
- package/lib/assets/docs/article/getting-start-tdd/node/index.md +56 -0
- package/lib/assets/docs/article/getting-start-tdd/php/01-todo-list-and-first-test.md +259 -0
- package/lib/assets/docs/article/getting-start-tdd/php/02-fake-it-and-triangulation.md +200 -0
- package/lib/assets/docs/article/getting-start-tdd/php/03-obvious-implementation-and-refactoring.md +248 -0
- package/lib/assets/docs/article/getting-start-tdd/php/04-version-control-and-conventional-commits.md +141 -0
- package/lib/assets/docs/article/getting-start-tdd/php/05-package-management-and-static-analysis.md +410 -0
- package/lib/assets/docs/article/getting-start-tdd/php/06-task-runner-and-ci-cd.md +321 -0
- package/lib/assets/docs/article/getting-start-tdd/php/07-encapsulation-and-polymorphism.md +372 -0
- package/lib/assets/docs/article/getting-start-tdd/php/08-design-patterns.md +453 -0
- package/lib/assets/docs/article/getting-start-tdd/php/09-solid-principles-and-module-design.md +460 -0
- package/lib/assets/docs/article/getting-start-tdd/php/10-higher-order-functions-and-composition.md +182 -0
- package/lib/assets/docs/article/getting-start-tdd/php/11-immutable-data-and-pipeline.md +266 -0
- package/lib/assets/docs/article/getting-start-tdd/php/12-error-handling-and-type-safety.md +308 -0
- package/lib/assets/docs/article/getting-start-tdd/php/index.md +84 -0
- package/lib/assets/docs/article/getting-start-tdd/python/01-todo-list-and-first-test.md +201 -0
- package/lib/assets/docs/article/getting-start-tdd/python/02-fake-it-and-triangulation.md +247 -0
- package/lib/assets/docs/article/getting-start-tdd/python/03-obvious-implementation-and-refactoring.md +199 -0
- package/lib/assets/docs/article/getting-start-tdd/python/04-version-control-and-conventional-commits.md +87 -0
- package/lib/assets/docs/article/getting-start-tdd/python/05-package-management-and-static-analysis.md +274 -0
- package/lib/assets/docs/article/getting-start-tdd/python/06-task-runner-and-ci-cd.md +190 -0
- package/lib/assets/docs/article/getting-start-tdd/python/07-encapsulation-and-polymorphism.md +208 -0
- package/lib/assets/docs/article/getting-start-tdd/python/08-design-patterns.md +172 -0
- package/lib/assets/docs/article/getting-start-tdd/python/09-solid-principles-and-module-design.md +130 -0
- package/lib/assets/docs/article/getting-start-tdd/python/10-higher-order-functions-and-composition.md +122 -0
- package/lib/assets/docs/article/getting-start-tdd/python/11-immutable-data-and-pipeline.md +116 -0
- package/lib/assets/docs/article/getting-start-tdd/python/12-error-handling-and-type-safety.md +126 -0
- package/lib/assets/docs/article/getting-start-tdd/python/index.md +55 -0
- package/lib/assets/docs/article/getting-start-tdd/ruby/01-todo-list-and-first-test.md +231 -0
- package/lib/assets/docs/article/getting-start-tdd/ruby/02-fake-it-and-triangulation.md +238 -0
- package/lib/assets/docs/article/getting-start-tdd/ruby/03-obvious-implementation-and-refactoring.md +228 -0
- package/lib/assets/docs/article/getting-start-tdd/ruby/04-version-control-and-conventional-commits.md +112 -0
- package/lib/assets/docs/article/getting-start-tdd/ruby/05-package-management-and-static-analysis.md +287 -0
- package/lib/assets/docs/article/getting-start-tdd/ruby/06-task-runner-and-ci-cd.md +248 -0
- package/lib/assets/docs/article/getting-start-tdd/ruby/07-encapsulation-and-polymorphism.md +279 -0
- package/lib/assets/docs/article/getting-start-tdd/ruby/08-design-patterns.md +329 -0
- package/lib/assets/docs/article/getting-start-tdd/ruby/09-solid-principles-and-module-design.md +196 -0
- package/lib/assets/docs/article/getting-start-tdd/ruby/10-higher-order-functions-and-composition.md +175 -0
- package/lib/assets/docs/article/getting-start-tdd/ruby/11-immutable-data-and-pipeline.md +233 -0
- package/lib/assets/docs/article/getting-start-tdd/ruby/12-error-handling-and-type-safety.md +398 -0
- package/lib/assets/docs/article/getting-start-tdd/ruby/index.md +83 -0
- package/lib/assets/docs/article/getting-start-tdd/rust/01-todo-list-and-first-test.md +211 -0
- package/lib/assets/docs/article/getting-start-tdd/rust/02-fake-it-and-triangulation.md +264 -0
- package/lib/assets/docs/article/getting-start-tdd/rust/03-obvious-implementation-and-refactoring.md +233 -0
- package/lib/assets/docs/article/getting-start-tdd/rust/04-version-control-and-conventional-commits.md +92 -0
- package/lib/assets/docs/article/getting-start-tdd/rust/05-package-management-and-static-analysis.md +212 -0
- package/lib/assets/docs/article/getting-start-tdd/rust/06-task-runner-and-ci-cd.md +164 -0
- package/lib/assets/docs/article/getting-start-tdd/rust/07-encapsulation-and-polymorphism.md +142 -0
- package/lib/assets/docs/article/getting-start-tdd/rust/08-design-patterns.md +145 -0
- package/lib/assets/docs/article/getting-start-tdd/rust/09-solid-principles-and-module-design.md +110 -0
- package/lib/assets/docs/article/getting-start-tdd/rust/10-higher-order-functions-and-composition.md +94 -0
- package/lib/assets/docs/article/getting-start-tdd/rust/11-immutable-data-and-pipeline.md +105 -0
- package/lib/assets/docs/article/getting-start-tdd/rust/12-error-handling-and-type-safety.md +112 -0
- package/lib/assets/docs/article/getting-start-tdd/rust/index.md +83 -0
- package/lib/assets/docs/article/getting-start-tdd/scala/01-todo-list-and-first-test.md +111 -0
- package/lib/assets/docs/article/getting-start-tdd/scala/02-fake-it-and-triangulation.md +107 -0
- package/lib/assets/docs/article/getting-start-tdd/scala/03-obvious-implementation-and-refactoring.md +99 -0
- package/lib/assets/docs/article/getting-start-tdd/scala/04-version-control-and-conventional-commits.md +123 -0
- package/lib/assets/docs/article/getting-start-tdd/scala/05-package-management-and-static-analysis.md +196 -0
- package/lib/assets/docs/article/getting-start-tdd/scala/06-task-runner-and-ci-cd.md +186 -0
- package/lib/assets/docs/article/getting-start-tdd/scala/07-case-classes-and-traits.md +139 -0
- package/lib/assets/docs/article/getting-start-tdd/scala/08-pattern-matching-and-sealed-traits.md +106 -0
- package/lib/assets/docs/article/getting-start-tdd/scala/09-packages-and-module-design.md +75 -0
- package/lib/assets/docs/article/getting-start-tdd/scala/10-higher-order-functions-and-composition.md +104 -0
- package/lib/assets/docs/article/getting-start-tdd/scala/11-collections-and-lazy-evaluation.md +94 -0
- package/lib/assets/docs/article/getting-start-tdd/scala/12-error-handling-and-type-safety.md +92 -0
- package/lib/assets/docs/article/getting-start-tdd/scala/index.md +65 -0
- package/lib/assets/docs/article/grokking-concurrency/all/index.md +404 -0
- package/lib/assets/docs/article/grokking-concurrency/all/part-1-ch02-sequential.md +554 -0
- package/lib/assets/docs/article/grokking-concurrency/all/part-2-ch04-05-threads.md +469 -0
- package/lib/assets/docs/article/grokking-concurrency/all/part-3-ch06-multitasking.md +520 -0
- package/lib/assets/docs/article/grokking-concurrency/all/part-4-ch07-parallel-patterns.md +420 -0
- package/lib/assets/docs/article/grokking-concurrency/all/part-5-ch08-09-synchronization.md +510 -0
- package/lib/assets/docs/article/grokking-concurrency/all/part-6-ch10-11-nonblocking-io.md +435 -0
- package/lib/assets/docs/article/grokking-concurrency/all/part-7-ch12-async.md +465 -0
- package/lib/assets/docs/article/grokking-concurrency/all/part-8-ch13-mapreduce.md +377 -0
- package/lib/assets/docs/article/grokking-concurrency/clojure/index.md +116 -0
- package/lib/assets/docs/article/grokking-concurrency/clojure/part-1.md +108 -0
- package/lib/assets/docs/article/grokking-concurrency/clojure/part-2.md +101 -0
- package/lib/assets/docs/article/grokking-concurrency/clojure/part-3.md +122 -0
- package/lib/assets/docs/article/grokking-concurrency/clojure/part-4.md +123 -0
- package/lib/assets/docs/article/grokking-concurrency/clojure/part-5.md +118 -0
- package/lib/assets/docs/article/grokking-concurrency/clojure/part-6.md +89 -0
- package/lib/assets/docs/article/grokking-concurrency/clojure/part-7.md +100 -0
- package/lib/assets/docs/article/grokking-concurrency/clojure/part-8.md +120 -0
- package/lib/assets/docs/article/grokking-concurrency/csharp/index.md +101 -0
- package/lib/assets/docs/article/grokking-concurrency/csharp/part-1.md +97 -0
- package/lib/assets/docs/article/grokking-concurrency/csharp/part-2.md +123 -0
- package/lib/assets/docs/article/grokking-concurrency/csharp/part-3.md +101 -0
- package/lib/assets/docs/article/grokking-concurrency/csharp/part-4.md +112 -0
- package/lib/assets/docs/article/grokking-concurrency/csharp/part-5.md +99 -0
- package/lib/assets/docs/article/grokking-concurrency/csharp/part-6.md +61 -0
- package/lib/assets/docs/article/grokking-concurrency/csharp/part-7.md +84 -0
- package/lib/assets/docs/article/grokking-concurrency/csharp/part-8.md +92 -0
- package/lib/assets/docs/article/grokking-concurrency/fsharp/index.md +65 -0
- package/lib/assets/docs/article/grokking-concurrency/fsharp/part-1.md +80 -0
- package/lib/assets/docs/article/grokking-concurrency/fsharp/part-2.md +103 -0
- package/lib/assets/docs/article/grokking-concurrency/fsharp/part-3.md +94 -0
- package/lib/assets/docs/article/grokking-concurrency/fsharp/part-4.md +110 -0
- package/lib/assets/docs/article/grokking-concurrency/fsharp/part-5.md +104 -0
- package/lib/assets/docs/article/grokking-concurrency/fsharp/part-6.md +93 -0
- package/lib/assets/docs/article/grokking-concurrency/fsharp/part-7.md +121 -0
- package/lib/assets/docs/article/grokking-concurrency/fsharp/part-8.md +107 -0
- package/lib/assets/docs/article/grokking-concurrency/haskell/index.md +248 -0
- package/lib/assets/docs/article/grokking-concurrency/haskell/part-1.md +96 -0
- package/lib/assets/docs/article/grokking-concurrency/haskell/part-2.md +96 -0
- package/lib/assets/docs/article/grokking-concurrency/haskell/part-3.md +91 -0
- package/lib/assets/docs/article/grokking-concurrency/haskell/part-4.md +106 -0
- package/lib/assets/docs/article/grokking-concurrency/haskell/part-5.md +99 -0
- package/lib/assets/docs/article/grokking-concurrency/haskell/part-6.md +95 -0
- package/lib/assets/docs/article/grokking-concurrency/haskell/part-7.md +111 -0
- package/lib/assets/docs/article/grokking-concurrency/haskell/part-8.md +118 -0
- package/lib/assets/docs/article/grokking-concurrency/index.md +66 -0
- package/lib/assets/docs/article/grokking-concurrency/java/index.md +102 -0
- package/lib/assets/docs/article/grokking-concurrency/java/part-1.md +308 -0
- package/lib/assets/docs/article/grokking-concurrency/java/part-2.md +334 -0
- package/lib/assets/docs/article/grokking-concurrency/java/part-3.md +221 -0
- package/lib/assets/docs/article/grokking-concurrency/java/part-4.md +213 -0
- package/lib/assets/docs/article/grokking-concurrency/java/part-5.md +112 -0
- package/lib/assets/docs/article/grokking-concurrency/java/part-6.md +69 -0
- package/lib/assets/docs/article/grokking-concurrency/java/part-7.md +101 -0
- package/lib/assets/docs/article/grokking-concurrency/java/part-8.md +101 -0
- package/lib/assets/docs/article/grokking-concurrency/python/index.md +313 -0
- package/lib/assets/docs/article/grokking-concurrency/python/part-1.md +239 -0
- package/lib/assets/docs/article/grokking-concurrency/python/part-2.md +418 -0
- package/lib/assets/docs/article/grokking-concurrency/python/part-3.md +227 -0
- package/lib/assets/docs/article/grokking-concurrency/python/part-4.md +299 -0
- package/lib/assets/docs/article/grokking-concurrency/python/part-5.md +315 -0
- package/lib/assets/docs/article/grokking-concurrency/python/part-6.md +297 -0
- package/lib/assets/docs/article/grokking-concurrency/python/part-7.md +314 -0
- package/lib/assets/docs/article/grokking-concurrency/python/part-8.md +360 -0
- package/lib/assets/docs/article/grokking-concurrency/rust/index.md +270 -0
- package/lib/assets/docs/article/grokking-concurrency/rust/part-1.md +108 -0
- package/lib/assets/docs/article/grokking-concurrency/rust/part-2.md +120 -0
- package/lib/assets/docs/article/grokking-concurrency/rust/part-3.md +126 -0
- package/lib/assets/docs/article/grokking-concurrency/rust/part-4.md +175 -0
- package/lib/assets/docs/article/grokking-concurrency/rust/part-5.md +158 -0
- package/lib/assets/docs/article/grokking-concurrency/rust/part-6.md +94 -0
- package/lib/assets/docs/article/grokking-concurrency/rust/part-7.md +133 -0
- package/lib/assets/docs/article/grokking-concurrency/rust/part-8.md +155 -0
- package/lib/assets/docs/article/grokking-concurrency/scala/index.md +69 -0
- package/lib/assets/docs/article/grokking-concurrency/scala/part-1.md +78 -0
- package/lib/assets/docs/article/grokking-concurrency/scala/part-2.md +112 -0
- package/lib/assets/docs/article/grokking-concurrency/scala/part-3.md +93 -0
- package/lib/assets/docs/article/grokking-concurrency/scala/part-4.md +110 -0
- package/lib/assets/docs/article/grokking-concurrency/scala/part-5.md +119 -0
- package/lib/assets/docs/article/grokking-concurrency/scala/part-6.md +83 -0
- package/lib/assets/docs/article/grokking-concurrency/scala/part-7.md +131 -0
- package/lib/assets/docs/article/grokking-concurrency/scala/part-8.md +129 -0
- package/lib/assets/docs/article/grokkingfp/all/index.md +368 -0
- package/lib/assets/docs/article/grokkingfp/all/part-1-ch01-fp-introduction.md +530 -0
- package/lib/assets/docs/article/grokkingfp/all/part-1-ch02-pure-functions.md +923 -0
- package/lib/assets/docs/article/grokkingfp/all/part-2-ch03-immutable-data.md +1122 -0
- package/lib/assets/docs/article/grokkingfp/all/part-2-ch04-higher-order-functions.md +1104 -0
- package/lib/assets/docs/article/grokkingfp/all/part-2-ch05-flatmap.md +1026 -0
- package/lib/assets/docs/article/grokkingfp/all/part-3-ch06-option.md +777 -0
- package/lib/assets/docs/article/grokkingfp/all/part-3-ch07-either-adt.md +871 -0
- package/lib/assets/docs/article/grokkingfp/all/part-4-ch08-io-monad.md +972 -0
- package/lib/assets/docs/article/grokkingfp/all/part-4-ch09-streams.md +926 -0
- package/lib/assets/docs/article/grokkingfp/all/part-5-ch10-concurrency.md +870 -0
- package/lib/assets/docs/article/grokkingfp/all/part-6-ch11-application.md +715 -0
- package/lib/assets/docs/article/grokkingfp/all/part-6-ch12-testing.md +626 -0
- package/lib/assets/docs/article/grokkingfp/all/writing-plan.md +696 -0
- package/lib/assets/docs/article/grokkingfp/clojure/index.md +276 -0
- package/lib/assets/docs/article/grokkingfp/clojure/part-1.md +667 -0
- package/lib/assets/docs/article/grokkingfp/clojure/part-2.md +643 -0
- package/lib/assets/docs/article/grokkingfp/clojure/part-3.md +620 -0
- package/lib/assets/docs/article/grokkingfp/clojure/part-4.md +697 -0
- package/lib/assets/docs/article/grokkingfp/clojure/part-5.md +751 -0
- package/lib/assets/docs/article/grokkingfp/clojure/part-6.md +721 -0
- package/lib/assets/docs/article/grokkingfp/csharp/index.md +246 -0
- package/lib/assets/docs/article/grokkingfp/csharp/part-1.md +811 -0
- package/lib/assets/docs/article/grokkingfp/csharp/part-2.md +971 -0
- package/lib/assets/docs/article/grokkingfp/csharp/part-3.md +981 -0
- package/lib/assets/docs/article/grokkingfp/csharp/part-4.md +949 -0
- package/lib/assets/docs/article/grokkingfp/csharp/part-5.md +947 -0
- package/lib/assets/docs/article/grokkingfp/csharp/part-6.md +739 -0
- package/lib/assets/docs/article/grokkingfp/elixir/index.md +203 -0
- package/lib/assets/docs/article/grokkingfp/elixir/part-1.md +710 -0
- package/lib/assets/docs/article/grokkingfp/elixir/part-2.md +838 -0
- package/lib/assets/docs/article/grokkingfp/elixir/part-3.md +985 -0
- package/lib/assets/docs/article/grokkingfp/elixir/part-4.md +974 -0
- package/lib/assets/docs/article/grokkingfp/elixir/part-5.md +1284 -0
- package/lib/assets/docs/article/grokkingfp/elixir/part-6.md +1047 -0
- package/lib/assets/docs/article/grokkingfp/fsharp/index.md +210 -0
- package/lib/assets/docs/article/grokkingfp/fsharp/part-1.md +714 -0
- package/lib/assets/docs/article/grokkingfp/fsharp/part-2.md +961 -0
- package/lib/assets/docs/article/grokkingfp/fsharp/part-3.md +972 -0
- package/lib/assets/docs/article/grokkingfp/fsharp/part-4.md +832 -0
- package/lib/assets/docs/article/grokkingfp/fsharp/part-5.md +911 -0
- package/lib/assets/docs/article/grokkingfp/fsharp/part-6.md +920 -0
- package/lib/assets/docs/article/grokkingfp/haskell/index.md +234 -0
- package/lib/assets/docs/article/grokkingfp/haskell/part-1.md +591 -0
- package/lib/assets/docs/article/grokkingfp/haskell/part-2.md +866 -0
- package/lib/assets/docs/article/grokkingfp/haskell/part-3.md +915 -0
- package/lib/assets/docs/article/grokkingfp/haskell/part-4.md +876 -0
- package/lib/assets/docs/article/grokkingfp/haskell/part-5.md +845 -0
- package/lib/assets/docs/article/grokkingfp/haskell/part-6.md +842 -0
- package/lib/assets/docs/article/grokkingfp/index.md +143 -0
- package/lib/assets/docs/article/grokkingfp/java/index.md +211 -0
- package/lib/assets/docs/article/grokkingfp/java/part-1.md +646 -0
- package/lib/assets/docs/article/grokkingfp/java/part-2.md +667 -0
- package/lib/assets/docs/article/grokkingfp/java/part-3.md +672 -0
- package/lib/assets/docs/article/grokkingfp/java/part-4.md +771 -0
- package/lib/assets/docs/article/grokkingfp/java/part-5.md +959 -0
- package/lib/assets/docs/article/grokkingfp/java/part-6.md +1324 -0
- package/lib/assets/docs/article/grokkingfp/python/index.md +258 -0
- package/lib/assets/docs/article/grokkingfp/python/part-1.md +437 -0
- package/lib/assets/docs/article/grokkingfp/python/part-2.md +958 -0
- package/lib/assets/docs/article/grokkingfp/python/part-3.md +1004 -0
- package/lib/assets/docs/article/grokkingfp/python/part-4.md +765 -0
- package/lib/assets/docs/article/grokkingfp/python/part-5.md +747 -0
- package/lib/assets/docs/article/grokkingfp/python/part-6.md +861 -0
- package/lib/assets/docs/article/grokkingfp/ruby/index.md +330 -0
- package/lib/assets/docs/article/grokkingfp/ruby/part-1.md +753 -0
- package/lib/assets/docs/article/grokkingfp/ruby/part-2.md +938 -0
- package/lib/assets/docs/article/grokkingfp/ruby/part-3.md +946 -0
- package/lib/assets/docs/article/grokkingfp/ruby/part-4.md +921 -0
- package/lib/assets/docs/article/grokkingfp/ruby/part-5.md +908 -0
- package/lib/assets/docs/article/grokkingfp/ruby/part-6.md +1410 -0
- package/lib/assets/docs/article/grokkingfp/rust/index.md +242 -0
- package/lib/assets/docs/article/grokkingfp/rust/part-1.md +634 -0
- package/lib/assets/docs/article/grokkingfp/rust/part-2.md +1060 -0
- package/lib/assets/docs/article/grokkingfp/rust/part-3.md +994 -0
- package/lib/assets/docs/article/grokkingfp/rust/part-4.md +571 -0
- package/lib/assets/docs/article/grokkingfp/rust/part-5.md +705 -0
- package/lib/assets/docs/article/grokkingfp/rust/part-6.md +508 -0
- package/lib/assets/docs/article/grokkingfp/scala/index.md +171 -0
- package/lib/assets/docs/article/grokkingfp/scala/part-1.md +541 -0
- package/lib/assets/docs/article/grokkingfp/scala/part-2.md +946 -0
- package/lib/assets/docs/article/grokkingfp/scala/part-3.md +917 -0
- package/lib/assets/docs/article/grokkingfp/scala/part-4.md +742 -0
- package/lib/assets/docs/article/grokkingfp/scala/part-5.md +722 -0
- package/lib/assets/docs/article/grokkingfp/scala/part-6.md +865 -0
- package/lib/assets/docs/article/grokkingfp/typescript/index.md +273 -0
- package/lib/assets/docs/article/grokkingfp/typescript/part-1.md +559 -0
- package/lib/assets/docs/article/grokkingfp/typescript/part-2.md +1129 -0
- package/lib/assets/docs/article/grokkingfp/typescript/part-3.md +842 -0
- package/lib/assets/docs/article/grokkingfp/typescript/part-4.md +1085 -0
- package/lib/assets/docs/article/grokkingfp/typescript/part-5.md +717 -0
- package/lib/assets/docs/article/grokkingfp/typescript/part-6.md +980 -0
- package/lib/assets/docs/article/index.md +36 -0
- package/lib/assets/docs/design/index.md +39 -27
- package/lib/assets/docs/development/index.md +11 -1
- package/lib/assets/docs/index.md +33 -106
- package/lib/assets/docs/operation/index.md +16 -6
- package/lib/assets/docs/reference/index.md +5 -4
- package/lib/assets/docs/requirements/index.md +13 -6
- package/lib/assets/docs/strategy/index.md +11 -4
- package/lib/assets/docs/template/index.md +9 -5
- package/lib/assets/mkdocs.yml +29 -17
- package/package.json +1 -1
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
# 第 12 章: エラーハンドリングと型安全性
|
|
2
|
+
|
|
3
|
+
## 12.1 はじめに
|
|
4
|
+
|
|
5
|
+
前章では LINQ チェーンによるパイプライン処理を学びました。この最終章では、C# の **Nullable 参照型** と **パターンマッチング** を使ったエラーハンドリングと型安全性を学びます。
|
|
6
|
+
|
|
7
|
+
## 12.2 Nullable 参照型
|
|
8
|
+
|
|
9
|
+
C# 8.0 以降では、Nullable 参照型を有効にすることで null 安全性をコンパイル時にチェックできます。
|
|
10
|
+
|
|
11
|
+
```xml
|
|
12
|
+
<PropertyGroup>
|
|
13
|
+
<Nullable>enable</Nullable>
|
|
14
|
+
</PropertyGroup>
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
### null 許容型と非 null 型
|
|
18
|
+
|
|
19
|
+
```csharp
|
|
20
|
+
string name = "hello"; // 非 null 型(null を代入するとコンパイラ警告)
|
|
21
|
+
string? nullable = null; // null 許容型(null を許容)
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
### FizzBuzzList での活用
|
|
25
|
+
|
|
26
|
+
`FindFirst` メソッドは一致する要素が見つからない場合に `null` を返します。
|
|
27
|
+
|
|
28
|
+
```csharp
|
|
29
|
+
public FizzBuzzValue? FindFirst(Func<FizzBuzzValue, bool> predicate)
|
|
30
|
+
{
|
|
31
|
+
return _values.FirstOrDefault(predicate);
|
|
32
|
+
}
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
戻り値の型 `FizzBuzzValue?` は「null の可能性がある」ことを明示します。Rust の `Option<T>` に相当する C# の表現方法です。
|
|
36
|
+
|
|
37
|
+
### テストの作成
|
|
38
|
+
|
|
39
|
+
```csharp
|
|
40
|
+
[Fact]
|
|
41
|
+
public void 最初の一致する値を取得できる()
|
|
42
|
+
{
|
|
43
|
+
var list = new FizzBuzzList(new List<FizzBuzzValue>
|
|
44
|
+
{
|
|
45
|
+
new FizzBuzzValue(1, "1"),
|
|
46
|
+
new FizzBuzzValue(3, "Fizz"),
|
|
47
|
+
new FizzBuzzValue(6, "Fizz")
|
|
48
|
+
});
|
|
49
|
+
var found = list.FindFirst(v => v.Value == "Fizz");
|
|
50
|
+
Assert.NotNull(found);
|
|
51
|
+
Assert.Equal(3, found.Number);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
[Fact]
|
|
55
|
+
public void 一致する値がない場合はnullを返す()
|
|
56
|
+
{
|
|
57
|
+
var list = new FizzBuzzList(new List<FizzBuzzValue>
|
|
58
|
+
{
|
|
59
|
+
new FizzBuzzValue(1, "1"),
|
|
60
|
+
new FizzBuzzValue(2, "2")
|
|
61
|
+
});
|
|
62
|
+
var found = list.FindFirst(v => v.Value == "Fizz");
|
|
63
|
+
Assert.Null(found);
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## 12.3 パターンマッチング
|
|
68
|
+
|
|
69
|
+
C# のパターンマッチングは `switch` 式で豊富なパターンを記述できます。
|
|
70
|
+
|
|
71
|
+
### switch 式
|
|
72
|
+
|
|
73
|
+
`FizzBuzzTypeFactory` は `switch` 式を使って型安全なファクトリを実現しています。
|
|
74
|
+
|
|
75
|
+
```csharp
|
|
76
|
+
public static IFizzBuzzType Create(int type)
|
|
77
|
+
{
|
|
78
|
+
return type switch
|
|
79
|
+
{
|
|
80
|
+
1 => new FizzBuzzType01(),
|
|
81
|
+
2 => new FizzBuzzType02(),
|
|
82
|
+
3 => new FizzBuzzType03(),
|
|
83
|
+
_ => throw new ArgumentException($"Invalid FizzBuzz type: {type}")
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
C# の `switch` 式は Rust の `match` 式に近く、値を返す式として使えます。`_` はデフォルトケース(Rust のワイルドカードに相当)です。
|
|
89
|
+
|
|
90
|
+
### 型パターン
|
|
91
|
+
|
|
92
|
+
`is` キーワードと型パターンで、オブジェクトの型をチェックしながらキャストできます。
|
|
93
|
+
|
|
94
|
+
```csharp
|
|
95
|
+
public bool Equals(object? obj)
|
|
96
|
+
{
|
|
97
|
+
if (obj is FizzBuzzValue other)
|
|
98
|
+
{
|
|
99
|
+
return Number == other.Number && Value == other.Value;
|
|
100
|
+
}
|
|
101
|
+
return false;
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
`obj is FizzBuzzValue other` は「`obj` が `FizzBuzzValue` 型であれば `other` に代入する」というパターンマッチングです。Rust の `if let Some(value) = option` に近い表現です。
|
|
106
|
+
|
|
107
|
+
### null チェックパターン
|
|
108
|
+
|
|
109
|
+
```csharp
|
|
110
|
+
public bool Equals(FizzBuzzValue? other)
|
|
111
|
+
{
|
|
112
|
+
if (other is null) return false; // null パターン
|
|
113
|
+
if (ReferenceEquals(this, other)) return true;
|
|
114
|
+
return Number == other.Number && Value == other.Value;
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### FizzBuzzTypeName enum と switch 式
|
|
119
|
+
|
|
120
|
+
```csharp
|
|
121
|
+
public enum FizzBuzzTypeName
|
|
122
|
+
{
|
|
123
|
+
Standard = 1,
|
|
124
|
+
NumberOnly = 2,
|
|
125
|
+
FizzBuzzOnly = 3
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
public static IFizzBuzzType Create(FizzBuzzTypeName name)
|
|
129
|
+
{
|
|
130
|
+
return Create((int)name);
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
enum を使うことで、タイプ番号をハードコーディングせずに型安全に指定できます。
|
|
135
|
+
|
|
136
|
+
### テストの作成
|
|
137
|
+
|
|
138
|
+
```csharp
|
|
139
|
+
public class FizzBuzzTypeFactoryTest
|
|
140
|
+
{
|
|
141
|
+
[Fact]
|
|
142
|
+
public void タイプ1を生成できる()
|
|
143
|
+
{
|
|
144
|
+
var type = FizzBuzzTypeFactory.Create(1);
|
|
145
|
+
Assert.IsType<FizzBuzzType01>(type);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
[Fact]
|
|
149
|
+
public void 不正なタイプは例外を投げる()
|
|
150
|
+
{
|
|
151
|
+
Assert.Throws<ArgumentException>(
|
|
152
|
+
() => FizzBuzzTypeFactory.Create(0));
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
[Fact]
|
|
156
|
+
public void Enumで生成できる()
|
|
157
|
+
{
|
|
158
|
+
var type = FizzBuzzTypeFactory.Create(FizzBuzzTypeName.Standard);
|
|
159
|
+
Assert.IsType<FizzBuzzType01>(type);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
## 12.4 例外ハンドリング
|
|
165
|
+
|
|
166
|
+
C# では `try-catch` と例外型の階層で例外を処理します。Rust の `Result<T, E>` とは異なるアプローチです。
|
|
167
|
+
|
|
168
|
+
```csharp
|
|
169
|
+
try
|
|
170
|
+
{
|
|
171
|
+
var type = FizzBuzzTypeFactory.Create(0);
|
|
172
|
+
}
|
|
173
|
+
catch (ArgumentException ex)
|
|
174
|
+
{
|
|
175
|
+
Console.WriteLine($"エラー: {ex.Message}");
|
|
176
|
+
}
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### Rust との比較
|
|
180
|
+
|
|
181
|
+
| 概念 | C# | Rust |
|
|
182
|
+
|------|------|------|
|
|
183
|
+
| エラーの表現 | 例外(`Exception`) | `Result<T, E>` |
|
|
184
|
+
| エラーの伝播 | `throw` / `try-catch` | `?` 演算子 |
|
|
185
|
+
| null の表現 | `T?`(Nullable 参照型) | `Option<T>` |
|
|
186
|
+
| null チェック | `is null` パターン | `match` / `if let` |
|
|
187
|
+
|
|
188
|
+
C# は例外ベースのエラーハンドリングですが、Nullable 参照型とパターンマッチングにより、null に起因するバグをコンパイル時に検出できるようになっています。
|
|
189
|
+
|
|
190
|
+
## 12.5 他言語との比較
|
|
191
|
+
|
|
192
|
+
| 概念 | C# | Rust | Java | TypeScript |
|
|
193
|
+
|------|------|------|------|------|
|
|
194
|
+
| エラーハンドリング | `try-catch` | `Result<T, E>` | `try-catch` | `try-catch` |
|
|
195
|
+
| null 安全 | `T?` (Nullable) | `Option<T>` | `Optional<T>` | `T \| null` |
|
|
196
|
+
| 列挙型 | `enum`(整数ベース) | `enum`(代数的データ型) | `enum`(クラスベース) | `enum`(数値/文字列) |
|
|
197
|
+
| パターンマッチ | `switch` 式 + 型パターン | `match`(網羅性チェック) | `switch` + `instanceof` | — |
|
|
198
|
+
| エラー伝播 | `throw` | `?` 演算子 | `throws` | `throw` |
|
|
199
|
+
|
|
200
|
+
## 12.6 まとめ
|
|
201
|
+
|
|
202
|
+
この章では以下を学びました。
|
|
203
|
+
|
|
204
|
+
| 概念 | C# の実現方法 |
|
|
205
|
+
|------|-------------|
|
|
206
|
+
| null 安全 | Nullable 参照型 (`T?`) + `<Nullable>enable</Nullable>` |
|
|
207
|
+
| パターンマッチ | `switch` 式 + 型パターン + null パターン |
|
|
208
|
+
| 型安全なファクトリ | `enum` + `switch` 式 |
|
|
209
|
+
| 例外ハンドリング | `ArgumentException` + `try-catch` |
|
|
210
|
+
|
|
211
|
+
全 12 章を通じて、C# の TDD 基本サイクル、開発環境の自動化、オブジェクト指向的な設計、関数型プログラミングの活用を一通り学びました。C# の強力な型システム、interface / abstract class、LINQ、Nullable 参照型、パターンマッチングは、安全で堅牢なソフトウェアを構築するための強力な基盤です。
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# テスト駆動開発から始める C# 入門
|
|
2
|
+
|
|
3
|
+
## 概要
|
|
4
|
+
|
|
5
|
+
FizzBuzz 問題を題材に、テスト駆動開発(TDD)の基本サイクルから、開発環境の整備、オブジェクト指向設計、関数型プログラミングの活用まで、C# の特徴を活かしながら段階的に学びます。
|
|
6
|
+
|
|
7
|
+
## 対象読者
|
|
8
|
+
|
|
9
|
+
- C# の基本文法を理解しているプログラミング学習者
|
|
10
|
+
- TDD を体験してみたい開発者
|
|
11
|
+
- オブジェクト指向設計や LINQ による関数型プログラミングに興味がある方
|
|
12
|
+
|
|
13
|
+
## 前提条件
|
|
14
|
+
|
|
15
|
+
- .NET 8.0 SDK 以降がインストールされていること
|
|
16
|
+
- dotnet CLI が利用可能であること(Nix 環境推奨: `nix develop .#dotnet`)
|
|
17
|
+
|
|
18
|
+
## C# の特徴
|
|
19
|
+
|
|
20
|
+
| 特徴 | 説明 |
|
|
21
|
+
|------|------|
|
|
22
|
+
| 静的型付け + 型推論 | 強力な型システムと `var` による型推論 |
|
|
23
|
+
| オブジェクト指向 | class, interface, abstract class による本格的な OOP |
|
|
24
|
+
| 関数型要素 | LINQ, ラムダ式, デリゲートによる関数型プログラミング |
|
|
25
|
+
| Nullable 参照型 | null 安全性をコンパイル時に検査 |
|
|
26
|
+
| パターンマッチング | switch 式、型パターン、プロパティパターン |
|
|
27
|
+
| クロスプラットフォーム | .NET による Windows / macOS / Linux 対応 |
|
|
28
|
+
|
|
29
|
+
## 開発ツール
|
|
30
|
+
|
|
31
|
+
| ツール | 用途 |
|
|
32
|
+
|--------|------|
|
|
33
|
+
| [xUnit.net](https://xunit.net/) | テスティングフレームワーク |
|
|
34
|
+
| [NuGet](https://www.nuget.org/) | パッケージマネージャ |
|
|
35
|
+
| [dotnet format](https://learn.microsoft.com/dotnet/core/tools/dotnet-format) | コードフォーマッター |
|
|
36
|
+
| [Microsoft.CodeAnalysis.Analyzers](https://github.com/dotnet/roslyn-analyzers) | 静的コード解析 |
|
|
37
|
+
| [Cake](https://cakebuild.net/) | ビルドスクリプト |
|
|
38
|
+
|
|
39
|
+
## 目次
|
|
40
|
+
|
|
41
|
+
### 第 1 部: TDD の基本サイクル
|
|
42
|
+
|
|
43
|
+
1. [第 1 章: TODO リストと最初のテスト](chapter01.md)
|
|
44
|
+
2. [第 2 章: 仮実装と三角測量](chapter02.md)
|
|
45
|
+
3. [第 3 章: 明白な実装とリファクタリング](chapter03.md)
|
|
46
|
+
|
|
47
|
+
### 第 2 部: 開発環境と自動化
|
|
48
|
+
|
|
49
|
+
4. [第 4 章: バージョン管理と Conventional Commits](chapter04.md)
|
|
50
|
+
5. [第 5 章: パッケージ管理と静的解析](chapter05.md)
|
|
51
|
+
6. [第 6 章: タスクランナーと CI/CD](chapter06.md)
|
|
52
|
+
|
|
53
|
+
### 第 3 部: オブジェクト指向設計
|
|
54
|
+
|
|
55
|
+
7. [第 7 章: カプセル化とポリモーフィズム](chapter07.md)
|
|
56
|
+
8. [第 8 章: デザインパターンの適用](chapter08.md)
|
|
57
|
+
9. [第 9 章: SOLID 原則とモジュール設計](chapter09.md)
|
|
58
|
+
|
|
59
|
+
### 第 4 部: 関数型プログラミングへの展開
|
|
60
|
+
|
|
61
|
+
10. [第 10 章: 高階関数と関数合成](chapter10.md)
|
|
62
|
+
11. [第 11 章: 不変データとパイプライン処理](chapter11.md)
|
|
63
|
+
12. [第 12 章: エラーハンドリングと型安全性](chapter12.md)
|
|
64
|
+
|
|
65
|
+
## 実装コード
|
|
66
|
+
|
|
67
|
+
本記事のすべてのコード例は `apps/dotnet/` に実装されています。
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
# 開発環境に入る
|
|
71
|
+
nix develop .#dotnet
|
|
72
|
+
|
|
73
|
+
# テスト実行
|
|
74
|
+
cd apps/dotnet
|
|
75
|
+
dotnet test
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## 参考文献
|
|
79
|
+
|
|
80
|
+
- Kent Beck 著『テスト駆動開発』
|
|
81
|
+
- Martin Fowler 著『リファクタリング: 既存のコードを安全に改善する』
|
|
82
|
+
- Robert C. Martin 著『Clean Code: アジャイルソフトウェア達人の技』
|
|
83
|
+
- Microsoft『C# プログラミングガイド』
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# 第 1 章: TODO リストと最初のテスト
|
|
2
|
+
|
|
3
|
+
## 1.1 はじめに
|
|
4
|
+
|
|
5
|
+
この章では、FizzBuzz 問題を小さな TODO リストに分解し、ExUnit で最初のテストを書きます。TDD の最初の一歩は、いきなり実装することではなく、失敗するテストから始めることです。
|
|
6
|
+
|
|
7
|
+
## 1.2 FizzBuzz の仕様と TODO リスト
|
|
8
|
+
|
|
9
|
+
対象の仕様は次のとおりです。
|
|
10
|
+
|
|
11
|
+
```text
|
|
12
|
+
1 から 100 までの数を出力する。
|
|
13
|
+
3 の倍数は Fizz、5 の倍数は Buzz、3 と 5 の両方の倍数は FizzBuzz を出力する。
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
まずは仕様を TODO リストに分解します。
|
|
17
|
+
|
|
18
|
+
- [ ] 数を文字列として返す
|
|
19
|
+
- [ ] 3 の倍数で Fizz を返す
|
|
20
|
+
- [ ] 5 の倍数で Buzz を返す
|
|
21
|
+
- [ ] 15 の倍数で FizzBuzz を返す
|
|
22
|
+
- [ ] 1 から 100 までの結果をリストで作る
|
|
23
|
+
|
|
24
|
+
最初のタスクとして「1 を渡すと文字列 1 を返す」だけを扱います。
|
|
25
|
+
|
|
26
|
+
## 1.3 ExUnit の基本
|
|
27
|
+
|
|
28
|
+
Elixir では `mix new` で作成したプロジェクトに ExUnit が標準で含まれます。最小のテストは `test` マクロと `assert` マクロで書けます。
|
|
29
|
+
|
|
30
|
+
```elixir
|
|
31
|
+
# test/fizz_buzz_test.exs
|
|
32
|
+
|
|
33
|
+
defmodule FizzBuzzTest do
|
|
34
|
+
use ExUnit.Case
|
|
35
|
+
|
|
36
|
+
test "1 を渡すと文字列 1 を返す" do
|
|
37
|
+
assert FizzBuzz.generate(1) == "1"
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
- `test` はテストケースを定義します。
|
|
43
|
+
- `assert` は期待値を検証します。
|
|
44
|
+
|
|
45
|
+
## 1.4 mix test の使い方
|
|
46
|
+
|
|
47
|
+
テスト実行は `mix test` を使います。
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
$ mix test
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
この時点では `FizzBuzz` モジュールが未実装なので、テストは失敗します。これが Red です。
|
|
54
|
+
|
|
55
|
+
## 1.5 Red から Green へ
|
|
56
|
+
|
|
57
|
+
### Red: 最初の失敗するテスト
|
|
58
|
+
|
|
59
|
+
先ほどのテストを実行すると、例えば次のように失敗します。
|
|
60
|
+
|
|
61
|
+
```text
|
|
62
|
+
** (UndefinedFunctionError) function FizzBuzz.generate/1 is undefined
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Green: 仮実装で通す
|
|
66
|
+
|
|
67
|
+
まずは最小限の仮実装でテストを通します。
|
|
68
|
+
|
|
69
|
+
```elixir
|
|
70
|
+
# lib/fizz_buzz.ex
|
|
71
|
+
|
|
72
|
+
defmodule FizzBuzz do
|
|
73
|
+
def generate(1), do: "1"
|
|
74
|
+
end
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
再度 `mix test` を実行します。
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
$ mix test
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
1 件のテストが成功すれば Green です。まだ汎用的ではありませんが、TDD ではこの小さな成功を積み重ねます。
|
|
84
|
+
|
|
85
|
+
## 1.6 まとめ
|
|
86
|
+
|
|
87
|
+
この章では、TODO リスト駆動で最小タスクを切り出し、ExUnit の `test` / `assert` と `mix test` の基本を確認しました。さらに、最初の失敗するテストを書いてから仮実装で成功させる Red → Green を体験しました。
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# 第 2 章: 仮実装と三角測量
|
|
2
|
+
|
|
3
|
+
## 2.1 はじめに
|
|
4
|
+
|
|
5
|
+
前章では「1 を渡すと文字列 1 を返す」を仮実装で通しました。この章では、仮実装から三角測量へ進み、実装を一般化します。
|
|
6
|
+
|
|
7
|
+
## 2.2 仮実装の限界
|
|
8
|
+
|
|
9
|
+
前章の実装は次のようなハードコードでした。
|
|
10
|
+
|
|
11
|
+
```elixir
|
|
12
|
+
defmodule FizzBuzz do
|
|
13
|
+
def generate(1), do: "1"
|
|
14
|
+
end
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
この実装は `1` 以外に対応できません。ここで新しいテストを追加して、一般化の必要性を明確にします。
|
|
18
|
+
|
|
19
|
+
## 2.3 三角測量: 2 を追加する
|
|
20
|
+
|
|
21
|
+
ExUnit の `describe` ブロックで関心ごとをまとめます。
|
|
22
|
+
|
|
23
|
+
```elixir
|
|
24
|
+
# test/fizz_buzz_test.exs
|
|
25
|
+
|
|
26
|
+
defmodule FizzBuzzTest do
|
|
27
|
+
use ExUnit.Case
|
|
28
|
+
|
|
29
|
+
describe "generate/1" do
|
|
30
|
+
test "1 を渡すと文字列 1 を返す" do
|
|
31
|
+
assert FizzBuzz.generate(1) == "1"
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
test "2 を渡すと文字列 2 を返す" do
|
|
35
|
+
assert FizzBuzz.generate(2) == "2"
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
`mix test` を実行すると失敗します。Green にするため、仮実装から一段進めます。
|
|
42
|
+
|
|
43
|
+
```elixir
|
|
44
|
+
# lib/fizz_buzz.ex
|
|
45
|
+
|
|
46
|
+
defmodule FizzBuzz do
|
|
47
|
+
def generate(n), do: Integer.to_string(n)
|
|
48
|
+
end
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
この変更で、`1` と `2` の両方が通ります。複数の具体例から実装を引き出すのが三角測量です。
|
|
52
|
+
|
|
53
|
+
## 2.4 3 の倍数で Fizz
|
|
54
|
+
|
|
55
|
+
次に、FizzBuzz の本題を追加します。
|
|
56
|
+
|
|
57
|
+
```elixir
|
|
58
|
+
# test/fizz_buzz_test.exs
|
|
59
|
+
|
|
60
|
+
defmodule FizzBuzzTest do
|
|
61
|
+
use ExUnit.Case
|
|
62
|
+
|
|
63
|
+
describe "generate/1" do
|
|
64
|
+
test "1 を渡すと文字列 1 を返す" do
|
|
65
|
+
assert FizzBuzz.generate(1) == "1"
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
test "2 を渡すと文字列 2 を返す" do
|
|
69
|
+
assert FizzBuzz.generate(2) == "2"
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
test "3 の倍数を渡すと Fizz を返す" do
|
|
73
|
+
assert FizzBuzz.generate(3) == "Fizz"
|
|
74
|
+
assert FizzBuzz.generate(6) == "Fizz"
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
これを通す最小実装は次のように書けます。
|
|
81
|
+
|
|
82
|
+
```elixir
|
|
83
|
+
# lib/fizz_buzz.ex
|
|
84
|
+
|
|
85
|
+
defmodule FizzBuzz do
|
|
86
|
+
def generate(n) when rem(n, 3) == 0, do: "Fizz"
|
|
87
|
+
def generate(n), do: Integer.to_string(n)
|
|
88
|
+
end
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
`mix test` が成功すれば Green です。
|
|
92
|
+
|
|
93
|
+
## 2.5 まとめ
|
|
94
|
+
|
|
95
|
+
この章では、ハードコードの仮実装から、複数ケースによる三角測量で一般化する流れを学びました。また、`describe` でテストを整理し、「2 を渡すと文字列 2」「3 の倍数で Fizz」を ExUnit で表現しました。
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# 第 3 章: 明白な実装とリファクタリング
|
|
2
|
+
|
|
3
|
+
## 3.1 はじめに
|
|
4
|
+
|
|
5
|
+
この章では FizzBuzz の仕様を `cond` で明白に実装し、1 から 100 までのリスト生成まで完成させます。最後に、読みやすさを高めるリファクタリングの観点を確認します。
|
|
6
|
+
|
|
7
|
+
## 3.2 cond による明白な実装
|
|
8
|
+
|
|
9
|
+
まずは必要なテストを追加します。
|
|
10
|
+
|
|
11
|
+
```elixir
|
|
12
|
+
# test/fizz_buzz_test.exs
|
|
13
|
+
|
|
14
|
+
defmodule FizzBuzzTest do
|
|
15
|
+
use ExUnit.Case
|
|
16
|
+
|
|
17
|
+
describe "generate/1" do
|
|
18
|
+
test "5 の倍数を渡すと Buzz を返す" do
|
|
19
|
+
assert FizzBuzz.generate(5) == "Buzz"
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
test "15 の倍数を渡すと FizzBuzz を返す" do
|
|
23
|
+
assert FizzBuzz.generate(15) == "FizzBuzz"
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
このテストを通す明白な実装は次のとおりです。
|
|
30
|
+
|
|
31
|
+
```elixir
|
|
32
|
+
# lib/fizz_buzz.ex
|
|
33
|
+
|
|
34
|
+
defmodule FizzBuzz do
|
|
35
|
+
def generate(n) do
|
|
36
|
+
cond do
|
|
37
|
+
rem(n, 15) == 0 -> "FizzBuzz"
|
|
38
|
+
rem(n, 3) == 0 -> "Fizz"
|
|
39
|
+
rem(n, 5) == 0 -> "Buzz"
|
|
40
|
+
true -> Integer.to_string(n)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
15 を先に判定することがポイントです。
|
|
47
|
+
|
|
48
|
+
## 3.3 1 から 100 までのリスト生成
|
|
49
|
+
|
|
50
|
+
続いて、結果一覧を作る関数のテストを書きます。
|
|
51
|
+
|
|
52
|
+
```elixir
|
|
53
|
+
# test/fizz_buzz_test.exs
|
|
54
|
+
|
|
55
|
+
defmodule FizzBuzzTest do
|
|
56
|
+
use ExUnit.Case
|
|
57
|
+
|
|
58
|
+
describe "generate_list/0" do
|
|
59
|
+
test "1 から 100 までの FizzBuzz リストを返す" do
|
|
60
|
+
result = FizzBuzz.generate_list()
|
|
61
|
+
|
|
62
|
+
assert length(result) == 100
|
|
63
|
+
assert Enum.at(result, 0) == "1"
|
|
64
|
+
assert Enum.at(result, 2) == "Fizz"
|
|
65
|
+
assert Enum.at(result, 4) == "Buzz"
|
|
66
|
+
assert Enum.at(result, 14) == "FizzBuzz"
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
実装はパイプライン演算子 `|>` を使うと読みやすくなります。
|
|
73
|
+
|
|
74
|
+
```elixir
|
|
75
|
+
# lib/fizz_buzz.ex
|
|
76
|
+
|
|
77
|
+
defmodule FizzBuzz do
|
|
78
|
+
def generate(n) do
|
|
79
|
+
cond do
|
|
80
|
+
rem(n, 15) == 0 -> "FizzBuzz"
|
|
81
|
+
rem(n, 3) == 0 -> "Fizz"
|
|
82
|
+
rem(n, 5) == 0 -> "Buzz"
|
|
83
|
+
true -> Integer.to_string(n)
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def generate_list do
|
|
88
|
+
1..100
|
|
89
|
+
|> Enum.map(&generate/1)
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
`|>` は「左の結果を右の関数に渡す」演算子です。データの流れを上から下に読めるため、処理の意図が明確になります。
|
|
95
|
+
|
|
96
|
+
## 3.4 リファクタリングのポイント
|
|
97
|
+
|
|
98
|
+
テストがすべて通る状態を保ちながら、次を確認します。
|
|
99
|
+
|
|
100
|
+
- 判定順が明確か(`15` → `3` → `5`)
|
|
101
|
+
- 重複した変換処理がないか
|
|
102
|
+
- 関数名が役割を正しく表しているか
|
|
103
|
+
- テストの責務が分離されているか(`describe` ごとに関心を分ける)
|
|
104
|
+
|
|
105
|
+
必要なら、テストデータを増やして安全に整理します。TDD では「動くこと」と「読みやすいこと」を両立させます。
|
|
106
|
+
|
|
107
|
+
## 3.5 まとめ
|
|
108
|
+
|
|
109
|
+
この章では、`cond` を使った明白な実装で `Buzz` と `FizzBuzz` を追加し、`1..100` のリスト生成を完成させました。さらに `|>` の基本と、テストを守りながら進めるリファクタリングの観点を確認しました。
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# 第 4 章: バージョン管理と Conventional Commits
|
|
2
|
+
|
|
3
|
+
## 4.1 はじめに
|
|
4
|
+
|
|
5
|
+
この章では、Elixir プロジェクトを安全に育てるための Git の基本操作と、Conventional Commits の実践方法を学びます。TDD では小さな変更を頻繁にコミットするため、履歴の読みやすさが品質に直結します。
|
|
6
|
+
|
|
7
|
+
## 4.2 Git の基本操作
|
|
8
|
+
|
|
9
|
+
まずは作業の最小ループを押さえます。
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
# 変更確認
|
|
13
|
+
git status
|
|
14
|
+
|
|
15
|
+
# 差分確認
|
|
16
|
+
git diff
|
|
17
|
+
|
|
18
|
+
# ステージング
|
|
19
|
+
git add lib/fizz_buzz.ex test/fizz_buzz_test.exs
|
|
20
|
+
|
|
21
|
+
# コミット
|
|
22
|
+
git commit -m "test: add test for fizzbuzz list generation"
|
|
23
|
+
|
|
24
|
+
# 履歴確認
|
|
25
|
+
git log --oneline --decorate -n 10
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
TDD では次の粒度でコミットすると履歴が明確です。
|
|
29
|
+
|
|
30
|
+
- Red: 失敗するテスト追加
|
|
31
|
+
- Green: テストを通す最小実装
|
|
32
|
+
- Refactor: 振る舞いを変えない整理
|
|
33
|
+
|
|
34
|
+
## 4.3 Conventional Commits のルール
|
|
35
|
+
|
|
36
|
+
Conventional Commits は、コミットメッセージを `type: summary` 形式で統一する規約です。
|
|
37
|
+
|
|
38
|
+
代表的な `type` は次のとおりです。
|
|
39
|
+
|
|
40
|
+
- `feat`: ユーザーに見える機能追加
|
|
41
|
+
- `fix`: バグ修正
|
|
42
|
+
- `docs`: ドキュメント変更
|
|
43
|
+
- `refactor`: 振る舞いを変えない内部改善
|
|
44
|
+
- `test`: テスト追加・修正
|
|
45
|
+
- `chore`: ビルドや設定などの雑務変更
|
|
46
|
+
|
|
47
|
+
例:
|
|
48
|
+
|
|
49
|
+
```text
|
|
50
|
+
feat: add generate_list/0 for 1..100 fizzbuzz output
|
|
51
|
+
fix: handle 15 multiples before 3 and 5 checks
|
|
52
|
+
docs: add chapter 4 for git workflow
|
|
53
|
+
test: add cases for fizz and buzz boundaries
|
|
54
|
+
refactor: simplify generate/1 with cond ordering
|
|
55
|
+
chore: update ci cache key for nix flake
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## 4.4 Elixir プロジェクトでのコミット例
|
|
59
|
+
|
|
60
|
+
`apps/elixir` の FizzBuzz 実装を例に、実際のコミット単位を示します。
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
# Red
|
|
64
|
+
git add test/fizz_buzz_test.exs
|
|
65
|
+
git commit -m "test: add failing test for generate_list/0"
|
|
66
|
+
|
|
67
|
+
# Green
|
|
68
|
+
git add lib/fizz_buzz.ex
|
|
69
|
+
git commit -m "feat: implement generate_list/0 with enum map"
|
|
70
|
+
|
|
71
|
+
# Refactor
|
|
72
|
+
git add lib/fizz_buzz.ex test/fizz_buzz_test.exs
|
|
73
|
+
git commit -m "refactor: improve readability of fizzbuzz conditions"
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
ポイントは、1 コミット 1 意図です。`feat` と `refactor` を同一コミットに混ぜないことで、レビューしやすくなります。
|
|
77
|
+
|
|
78
|
+
## 4.5 .gitignore の設定
|
|
79
|
+
|
|
80
|
+
Elixir ではビルド成果物と依存パッケージを Git 管理対象から除外します。`apps/elixir/.gitignore` には少なくとも次を含めます。
|
|
81
|
+
|
|
82
|
+
```gitignore
|
|
83
|
+
/_build/
|
|
84
|
+
/deps/
|
|
85
|
+
.elixir_ls/
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
- `/_build/`: `mix compile` の生成物
|
|
89
|
+
- `/deps/`: `mix deps.get` で取得される依存コード
|
|
90
|
+
- `.elixir_ls/`: Elixir Language Server の作業ディレクトリ
|
|
91
|
+
|
|
92
|
+
これらを除外すると、環境依存ファイルの混入を防げます。
|
|
93
|
+
|
|
94
|
+
## 4.6 まとめ
|
|
95
|
+
|
|
96
|
+
この章では、Git の基本操作、Conventional Commits の主要ルール、Elixir プロジェクトでの具体的なコミット例、`.gitignore` の重要設定を確認しました。以降の章では、この履歴運用を前提に品質チェックと自動化を強化します。
|