rkoans 0.0.1 → 0.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.
Files changed (460) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +13 -0
  3. data/CURRICULUM.md +86 -0
  4. data/README.md +77 -0
  5. data/THIRD_PARTY_NOTICES.md +30 -0
  6. data/exercises/about-array-assignment/about_array_assignment.rb +45 -0
  7. data/exercises/about-array-assignment/brief.md +11 -0
  8. data/exercises/about-array-assignment/hint.md +11 -0
  9. data/exercises/about-arrays/about_arrays.rb +77 -0
  10. data/exercises/about-arrays/brief.md +16 -0
  11. data/exercises/about-arrays/hint.md +13 -0
  12. data/exercises/about-asserts/about_asserts.rb +22 -0
  13. data/exercises/about-asserts/brief.md +22 -0
  14. data/exercises/about-asserts/hint.md +10 -0
  15. data/exercises/about-blocks/about_blocks.rb +76 -0
  16. data/exercises/about-blocks/brief.md +44 -0
  17. data/exercises/about-blocks/hint.md +7 -0
  18. data/exercises/about-class-methods/about_class_methods.rb +105 -0
  19. data/exercises/about-class-methods/brief.md +73 -0
  20. data/exercises/about-class-methods/hint.md +8 -0
  21. data/exercises/about-classes/about_classes.rb +131 -0
  22. data/exercises/about-classes/brief.md +73 -0
  23. data/exercises/about-classes/hint.md +7 -0
  24. data/exercises/about-constants/about_constants.rb +49 -0
  25. data/exercises/about-constants/brief.md +51 -0
  26. data/exercises/about-constants/hint.md +7 -0
  27. data/exercises/about-control-statements/about_control_statements.rb +152 -0
  28. data/exercises/about-control-statements/brief.md +9 -0
  29. data/exercises/about-control-statements/hint.md +7 -0
  30. data/exercises/about-dice-project/about_dice_project.rb +27 -0
  31. data/exercises/about-dice-project/brief.md +12 -0
  32. data/exercises/about-dice-project/hint.md +5 -0
  33. data/exercises/about-exceptions/about_exceptions.rb +84 -0
  34. data/exercises/about-exceptions/brief.md +19 -0
  35. data/exercises/about-exceptions/hint.md +8 -0
  36. data/exercises/about-extra-credit/about_extra_credit.rb +117 -0
  37. data/exercises/about-extra-credit/brief.md +28 -0
  38. data/exercises/about-extra-credit/hint.md +5 -0
  39. data/exercises/about-hashes/about_hashes.rb +160 -0
  40. data/exercises/about-hashes/brief.md +9 -0
  41. data/exercises/about-hashes/hint.md +8 -0
  42. data/exercises/about-inheritance/about_inheritance.rb +63 -0
  43. data/exercises/about-inheritance/brief.md +50 -0
  44. data/exercises/about-inheritance/hint.md +8 -0
  45. data/exercises/about-iteration/about_iteration.rb +96 -0
  46. data/exercises/about-iteration/brief.md +26 -0
  47. data/exercises/about-iteration/hint.md +6 -0
  48. data/exercises/about-keyword-arguments/about_keyword_arguments.rb +56 -0
  49. data/exercises/about-keyword-arguments/brief.md +28 -0
  50. data/exercises/about-keyword-arguments/hint.md +7 -0
  51. data/exercises/about-message-passing/about_message_passing.rb +112 -0
  52. data/exercises/about-message-passing/brief.md +59 -0
  53. data/exercises/about-message-passing/hint.md +8 -0
  54. data/exercises/about-methods/about_methods.rb +104 -0
  55. data/exercises/about-methods/brief.md +55 -0
  56. data/exercises/about-methods/hint.md +8 -0
  57. data/exercises/about-modules/about_modules.rb +43 -0
  58. data/exercises/about-modules/brief.md +44 -0
  59. data/exercises/about-modules/hint.md +8 -0
  60. data/exercises/about-nil/about_nil.rb +29 -0
  61. data/exercises/about-nil/brief.md +12 -0
  62. data/exercises/about-nil/hint.md +11 -0
  63. data/exercises/about-objects/about_objects.rb +51 -0
  64. data/exercises/about-objects/brief.md +14 -0
  65. data/exercises/about-objects/hint.md +12 -0
  66. data/exercises/about-open-classes/about_open_classes.rb +38 -0
  67. data/exercises/about-open-classes/brief.md +34 -0
  68. data/exercises/about-open-classes/hint.md +7 -0
  69. data/exercises/about-pattern-matching/about_pattern_matching.rb +106 -0
  70. data/exercises/about-pattern-matching/brief.md +124 -0
  71. data/exercises/about-pattern-matching/hint.md +8 -0
  72. data/exercises/about-proxy-object-project/about_proxy_object_project.rb +43 -0
  73. data/exercises/about-proxy-object-project/brief.md +10 -0
  74. data/exercises/about-proxy-object-project/hint.md +5 -0
  75. data/exercises/about-regular-expressions/about_regular_expressions.rb +174 -0
  76. data/exercises/about-regular-expressions/brief.md +9 -0
  77. data/exercises/about-regular-expressions/hint.md +8 -0
  78. data/exercises/about-sandwich-code/about_sandwich_code.rb +58 -0
  79. data/exercises/about-sandwich-code/brief.md +14 -0
  80. data/exercises/about-sandwich-code/hint.md +5 -0
  81. data/exercises/about-scope/about_scope.rb +76 -0
  82. data/exercises/about-scope/brief.md +35 -0
  83. data/exercises/about-scope/hint.md +8 -0
  84. data/exercises/about-scoring-project/about_scoring_project.rb +16 -0
  85. data/exercises/about-scoring-project/brief.md +10 -0
  86. data/exercises/about-scoring-project/hint.md +5 -0
  87. data/exercises/about-strings/about_strings.rb +142 -0
  88. data/exercises/about-strings/brief.md +22 -0
  89. data/exercises/about-strings/hint.md +11 -0
  90. data/exercises/about-symbols/about_symbols.rb +53 -0
  91. data/exercises/about-symbols/brief.md +21 -0
  92. data/exercises/about-symbols/hint.md +12 -0
  93. data/exercises/about-to-str/about_to_str.rb +49 -0
  94. data/exercises/about-to-str/brief.md +37 -0
  95. data/exercises/about-to-str/hint.md +7 -0
  96. data/exercises/about-triangle-project/about_triangle_project.rb +15 -0
  97. data/exercises/about-triangle-project/brief.md +11 -0
  98. data/exercises/about-triangle-project/hint.md +5 -0
  99. data/exercises/about-triangle-project-two/about_triangle_project_two.rb +22 -0
  100. data/exercises/about-triangle-project-two/brief.md +10 -0
  101. data/exercises/about-triangle-project-two/hint.md +5 -0
  102. data/exercises/about-true-and-false/about_true_and_false.rb +26 -0
  103. data/exercises/about-true-and-false/brief.md +22 -0
  104. data/exercises/about-true-and-false/hint.md +7 -0
  105. data/exercises/blocks-and-methods/blocks_and_methods.rb +14 -0
  106. data/exercises/blocks-and-methods/brief.md +8 -0
  107. data/exercises/blocks-and-methods/hint.md +6 -0
  108. data/exercises/catalog.json +61 -0
  109. data/exercises/class-state/brief.md +8 -0
  110. data/exercises/class-state/class_state.rb +39 -0
  111. data/exercises/class-state/hint.md +5 -0
  112. data/exercises/closure-capture/brief.md +8 -0
  113. data/exercises/closure-capture/closure_capture.rb +21 -0
  114. data/exercises/closure-capture/hint.md +5 -0
  115. data/exercises/collection-basics/brief.md +8 -0
  116. data/exercises/collection-basics/collection_basics.rb +16 -0
  117. data/exercises/collection-basics/hint.md +6 -0
  118. data/exercises/constant-scope/brief.md +8 -0
  119. data/exercises/constant-scope/constant_scope.rb +18 -0
  120. data/exercises/constant-scope/hint.md +5 -0
  121. data/exercises/core-protocols/brief.md +8 -0
  122. data/exercises/core-protocols/core_protocols.rb +43 -0
  123. data/exercises/core-protocols/hint.md +5 -0
  124. data/exercises/delegation/brief.md +8 -0
  125. data/exercises/delegation/delegation.rb +20 -0
  126. data/exercises/delegation/hint.md +5 -0
  127. data/exercises/dynamic-methods/brief.md +8 -0
  128. data/exercises/dynamic-methods/dynamic_methods.rb +33 -0
  129. data/exercises/dynamic-methods/hint.md +5 -0
  130. data/exercises/exception-flow/brief.md +8 -0
  131. data/exercises/exception-flow/exception_flow.rb +27 -0
  132. data/exercises/exception-flow/hint.md +5 -0
  133. data/exercises/heredoc-layout/brief.md +14 -0
  134. data/exercises/heredoc-layout/heredoc_layout.rb +25 -0
  135. data/exercises/heredoc-layout/hint.md +9 -0
  136. data/exercises/keyword-forwarding/brief.md +8 -0
  137. data/exercises/keyword-forwarding/hint.md +5 -0
  138. data/exercises/keyword-forwarding/keyword_forwarding.rb +27 -0
  139. data/exercises/lazy-enumeration/brief.md +8 -0
  140. data/exercises/lazy-enumeration/hint.md +5 -0
  141. data/exercises/lazy-enumeration/lazy_enumeration.rb +16 -0
  142. data/exercises/literals-and-operators/brief.md +20 -0
  143. data/exercises/literals-and-operators/hint.md +5 -0
  144. data/exercises/literals-and-operators/literals_and_operators.rb +15 -0
  145. data/exercises/method-contracts/brief.md +8 -0
  146. data/exercises/method-contracts/hint.md +5 -0
  147. data/exercises/method-contracts/method_contracts.rb +22 -0
  148. data/exercises/method-lookup/brief.md +8 -0
  149. data/exercises/method-lookup/hint.md +5 -0
  150. data/exercises/method-lookup/method_lookup.rb +26 -0
  151. data/exercises/nonlocal-exit/brief.md +8 -0
  152. data/exercises/nonlocal-exit/hint.md +5 -0
  153. data/exercises/nonlocal-exit/nonlocal_exit.rb +29 -0
  154. data/exercises/numbered-parameters/brief.md +18 -0
  155. data/exercises/numbered-parameters/hint.md +5 -0
  156. data/exercises/numbered-parameters/numbered_parameters.rb +18 -0
  157. data/exercises/numeric-precision/brief.md +8 -0
  158. data/exercises/numeric-precision/hint.md +5 -0
  159. data/exercises/numeric-precision/numeric_precision.rb +17 -0
  160. data/exercises/pattern-matching/brief.md +8 -0
  161. data/exercises/pattern-matching/hint.md +5 -0
  162. data/exercises/pattern-matching/pattern_matching.rb +22 -0
  163. data/exercises/refinement-scope/brief.md +8 -0
  164. data/exercises/refinement-scope/hint.md +5 -0
  165. data/exercises/refinement-scope/refinement_scope.rb +33 -0
  166. data/exercises/regexp-captures/brief.md +8 -0
  167. data/exercises/regexp-captures/hint.md +5 -0
  168. data/exercises/regexp-captures/regexp_captures.rb +25 -0
  169. data/exercises/runtime-context/brief.md +20 -0
  170. data/exercises/runtime-context/hint.md +8 -0
  171. data/exercises/runtime-context/runtime_context.rb +11 -0
  172. data/exercises/shared-rows/brief.md +8 -0
  173. data/exercises/shared-rows/hint.md +7 -0
  174. data/exercises/shared-rows/shared_rows.rb +13 -0
  175. data/exercises/singleton-pattern/brief.md +8 -0
  176. data/exercises/singleton-pattern/hint.md +5 -0
  177. data/exercises/singleton-pattern/singleton_pattern.rb +20 -0
  178. data/exercises/time-and-date/brief.md +8 -0
  179. data/exercises/time-and-date/hint.md +5 -0
  180. data/exercises/time-and-date/time_and_date.rb +21 -0
  181. data/exercises/visibility/brief.md +8 -0
  182. data/exercises/visibility/hint.md +5 -0
  183. data/exercises/visibility/visibility.rb +32 -0
  184. data/lib/rkoans/catalog.rb +31 -0
  185. data/lib/rkoans/checker.rb +62 -0
  186. data/lib/rkoans/cli.rb +79 -0
  187. data/lib/rkoans/error.rb +6 -0
  188. data/lib/rkoans/exercise.rb +50 -0
  189. data/lib/rkoans/keyboard.rb +51 -0
  190. data/lib/rkoans/progress.rb +39 -0
  191. data/lib/rkoans/selection.rb +31 -0
  192. data/lib/rkoans/session.rb +127 -0
  193. data/lib/rkoans/terminal_view.rb +99 -0
  194. data/lib/rkoans/version.rb +1 -1
  195. data/lib/rkoans/watcher.rb +58 -0
  196. data/lib/rkoans.rb +13 -3
  197. data/sig/about_array_assignment_acceptance_test.rbs +3 -0
  198. data/sig/about_arrays_acceptance_test.rbs +3 -0
  199. data/sig/about_asserts_command_test.rbs +4 -0
  200. data/sig/about_blocks_acceptance_test.rbs +3 -0
  201. data/sig/about_class_methods_acceptance_test.rbs +3 -0
  202. data/sig/about_classes_acceptance_test.rbs +3 -0
  203. data/sig/about_constants_acceptance_test.rbs +3 -0
  204. data/sig/about_control_statements_acceptance_test.rbs +3 -0
  205. data/sig/about_dice_project_acceptance_test.rbs +3 -0
  206. data/sig/about_exceptions_acceptance_test.rbs +3 -0
  207. data/sig/about_extra_credit_acceptance_test.rbs +5 -0
  208. data/sig/about_hashes_acceptance_test.rbs +3 -0
  209. data/sig/about_inheritance_acceptance_test.rbs +3 -0
  210. data/sig/about_iteration_acceptance_test.rbs +3 -0
  211. data/sig/about_keyword_arguments_acceptance_test.rbs +3 -0
  212. data/sig/about_message_passing_acceptance_test.rbs +3 -0
  213. data/sig/about_methods_acceptance_test.rbs +3 -0
  214. data/sig/about_modules_acceptance_test.rbs +3 -0
  215. data/sig/about_nil_acceptance_test.rbs +3 -0
  216. data/sig/about_objects_acceptance_test.rbs +3 -0
  217. data/sig/about_open_classes_acceptance_test.rbs +3 -0
  218. data/sig/about_pattern_matching_acceptance_test.rbs +3 -0
  219. data/sig/about_proxy_object_project_acceptance_test.rbs +3 -0
  220. data/sig/about_regular_expressions_acceptance_test.rbs +3 -0
  221. data/sig/about_sandwich_code_acceptance_test.rbs +3 -0
  222. data/sig/about_scope_acceptance_test.rbs +3 -0
  223. data/sig/about_scoring_project_acceptance_test.rbs +3 -0
  224. data/sig/about_strings_acceptance_test.rbs +3 -0
  225. data/sig/about_symbols_acceptance_test.rbs +3 -0
  226. data/sig/about_to_str_acceptance_test.rbs +3 -0
  227. data/sig/about_triangle_project_acceptance_test.rbs +3 -0
  228. data/sig/about_triangle_project_two_acceptance_test.rbs +3 -0
  229. data/sig/about_true_and_false_command_test.rbs +4 -0
  230. data/sig/catalog_error_command_test.rbs +4 -0
  231. data/sig/checker_test.rbs +9 -0
  232. data/sig/class_state_acceptance_test.rbs +3 -0
  233. data/sig/closure_capture_acceptance_test.rbs +3 -0
  234. data/sig/command_support.rbs +18 -0
  235. data/sig/command_test.rbs +5 -0
  236. data/sig/constant_scope_acceptance_test.rbs +3 -0
  237. data/sig/core_protocols_acceptance_test.rbs +3 -0
  238. data/sig/curriculum_cop_test.rbs +9 -0
  239. data/sig/delegation_acceptance_test.rbs +3 -0
  240. data/sig/dynamic_methods_acceptance_test.rbs +3 -0
  241. data/sig/exception_flow_acceptance_test.rbs +3 -0
  242. data/sig/exercise_test.rbs +3 -0
  243. data/sig/exercises/about_array_assignment.rbs +36 -0
  244. data/sig/exercises/about_arrays.rbs +51 -0
  245. data/sig/exercises/about_asserts.rbs +23 -0
  246. data/sig/exercises/about_blocks.rbs +40 -0
  247. data/sig/exercises/about_class_methods.rbs +62 -0
  248. data/sig/exercises/about_classes.rbs +88 -0
  249. data/sig/exercises/about_constants.rbs +53 -0
  250. data/sig/exercises/about_control_statements.rbs +46 -0
  251. data/sig/exercises/about_dice_project.rbs +16 -0
  252. data/sig/exercises/about_exceptions.rbs +36 -0
  253. data/sig/exercises/about_extra_credit.rbs +36 -0
  254. data/sig/exercises/about_hashes.rbs +62 -0
  255. data/sig/exercises/about_inheritance.rbs +50 -0
  256. data/sig/exercises/about_iteration.rbs +37 -0
  257. data/sig/exercises/about_keyword_arguments.rbs +33 -0
  258. data/sig/exercises/about_message_passing.rbs +68 -0
  259. data/sig/exercises/about_methods.rbs +68 -0
  260. data/sig/exercises/about_modules.rbs +38 -0
  261. data/sig/exercises/about_nil.rbs +23 -0
  262. data/sig/exercises/about_objects.rbs +38 -0
  263. data/sig/exercises/about_open_classes.rbs +31 -0
  264. data/sig/exercises/about_pattern_matching.rbs +65 -0
  265. data/sig/exercises/about_proxy_object_project.rbs +31 -0
  266. data/sig/exercises/about_regular_expressions.rbs +83 -0
  267. data/sig/exercises/about_sandwich_code.rbs +17 -0
  268. data/sig/exercises/about_scope.rbs +59 -0
  269. data/sig/exercises/about_scoring_project.rbs +16 -0
  270. data/sig/exercises/about_strings.rbs +85 -0
  271. data/sig/exercises/about_symbols.rbs +46 -0
  272. data/sig/exercises/about_to_str.rbs +36 -0
  273. data/sig/exercises/about_triangle_project.rbs +11 -0
  274. data/sig/exercises/about_triangle_project_two.rbs +12 -0
  275. data/sig/exercises/about_true_and_false.rbs +27 -0
  276. data/sig/exercises/blocks_and_methods.rbs +11 -0
  277. data/sig/exercises/class_state.rbs +19 -0
  278. data/sig/exercises/closure_capture.rbs +10 -0
  279. data/sig/exercises/collection_basics.rbs +6 -0
  280. data/sig/exercises/collection_basics_test.rbs +4 -0
  281. data/sig/exercises/constant_scope.rbs +11 -0
  282. data/sig/exercises/core_protocols.rbs +20 -0
  283. data/sig/exercises/delegation.rbs +14 -0
  284. data/sig/exercises/dynamic_methods.rbs +13 -0
  285. data/sig/exercises/exception_flow.rbs +11 -0
  286. data/sig/exercises/heredoc_layout.rbs +11 -0
  287. data/sig/exercises/keyword_forwarding.rbs +12 -0
  288. data/sig/exercises/lazy_enumeration.rbs +10 -0
  289. data/sig/exercises/literals_and_operators.rbs +12 -0
  290. data/sig/exercises/method_contracts.rbs +11 -0
  291. data/sig/exercises/method_lookup.rbs +16 -0
  292. data/sig/exercises/nonlocal_exit.rbs +14 -0
  293. data/sig/exercises/numbered_parameters.rbs +11 -0
  294. data/sig/exercises/numeric_precision.rbs +11 -0
  295. data/sig/exercises/pattern_matching.rbs +10 -0
  296. data/sig/exercises/refinement_scope.rbs +18 -0
  297. data/sig/exercises/regexp_captures.rbs +11 -0
  298. data/sig/exercises/runtime_context.rbs +23 -0
  299. data/sig/exercises/shared_rows.rbs +11 -0
  300. data/sig/exercises/singleton_pattern.rbs +14 -0
  301. data/sig/exercises/time_and_date.rbs +11 -0
  302. data/sig/exercises/visibility.rbs +18 -0
  303. data/sig/fixture_support.rbs +11 -0
  304. data/sig/help_hint_command_test.rbs +8 -0
  305. data/sig/heredoc_layout_acceptance_test.rbs +3 -0
  306. data/sig/keyboard_session_test.rbs +9 -0
  307. data/sig/keyword_forwarding_acceptance_test.rbs +3 -0
  308. data/sig/lazy_enumeration_acceptance_test.rbs +3 -0
  309. data/sig/literals_and_operators_acceptance_test.rbs +3 -0
  310. data/sig/method_contracts_acceptance_test.rbs +3 -0
  311. data/sig/method_lookup_acceptance_test.rbs +3 -0
  312. data/sig/nonlocal_exit_acceptance_test.rbs +3 -0
  313. data/sig/numbered_parameters_acceptance_test.rbs +3 -0
  314. data/sig/numeric_precision_acceptance_test.rbs +4 -0
  315. data/sig/packaging_test.rbs +3 -0
  316. data/sig/pattern_matching_acceptance_test.rbs +3 -0
  317. data/sig/reference_solutions_test.rbs +3 -0
  318. data/sig/refinement_scope_acceptance_test.rbs +3 -0
  319. data/sig/regexp_captures_acceptance_test.rbs +4 -0
  320. data/sig/rkoans/catalog.rbs +11 -0
  321. data/sig/rkoans/checker.rbs +22 -0
  322. data/sig/rkoans/cli.rbs +21 -0
  323. data/sig/rkoans/exercise.rbs +18 -0
  324. data/sig/rkoans/keyboard.rbs +13 -0
  325. data/sig/rkoans/progress.rbs +9 -0
  326. data/sig/rkoans/selection.rbs +9 -0
  327. data/sig/rkoans/session.rbs +30 -0
  328. data/sig/rkoans/terminal_view.rbs +24 -0
  329. data/sig/rkoans/watcher.rbs +18 -0
  330. data/sig/rkoans.rbs +2 -0
  331. data/sig/runtime_context_command_test.rbs +4 -0
  332. data/sig/selection_command_test.rbs +5 -0
  333. data/sig/session_command_test.rbs +12 -0
  334. data/sig/session_edge_cases_test.rbs +4 -0
  335. data/sig/shared_rows_acceptance_test.rbs +3 -0
  336. data/sig/singleton_pattern_acceptance_test.rbs +3 -0
  337. data/sig/time_and_date_acceptance_test.rbs +4 -0
  338. data/sig/visibility_acceptance_test.rbs +4 -0
  339. data/sig/watcher_test.rbs +3 -0
  340. data/solutions/about-array-assignment/about_array_assignment.rb +36 -0
  341. data/solutions/about-arrays/about_arrays.rb +53 -0
  342. data/solutions/about-asserts/about_asserts.rb +22 -0
  343. data/solutions/about-blocks/about_blocks.rb +30 -0
  344. data/solutions/about-class-methods/about_class_methods.rb +36 -0
  345. data/solutions/about-classes/about_classes.rb +40 -0
  346. data/solutions/about-constants/about_constants.rb +26 -0
  347. data/solutions/about-control-statements/about_control_statements.rb +35 -0
  348. data/solutions/about-dice-project/about_dice_project.rb +27 -0
  349. data/solutions/about-exceptions/about_exceptions.rb +30 -0
  350. data/solutions/about-extra-credit/about_extra_credit.rb +114 -0
  351. data/solutions/about-hashes/about_hashes.rb +52 -0
  352. data/solutions/about-inheritance/about_inheritance.rb +27 -0
  353. data/solutions/about-iteration/about_iteration.rb +31 -0
  354. data/solutions/about-keyword-arguments/about_keyword_arguments.rb +28 -0
  355. data/solutions/about-message-passing/about_message_passing.rb +38 -0
  356. data/solutions/about-methods/about_methods.rb +39 -0
  357. data/solutions/about-modules/about_modules.rb +23 -0
  358. data/solutions/about-nil/about_nil.rb +23 -0
  359. data/solutions/about-objects/about_objects.rb +34 -0
  360. data/solutions/about-open-classes/about_open_classes.rb +23 -0
  361. data/solutions/about-pattern-matching/about_pattern_matching.rb +39 -0
  362. data/solutions/about-proxy-object-project/about_proxy_object_project.rb +44 -0
  363. data/solutions/about-regular-expressions/about_regular_expressions.rb +60 -0
  364. data/solutions/about-sandwich-code/about_sandwich_code.rb +60 -0
  365. data/solutions/about-scope/about_scope.rb +33 -0
  366. data/solutions/about-scoring-project/about_scoring_project.rb +19 -0
  367. data/solutions/about-strings/about_strings.rb +56 -0
  368. data/solutions/about-symbols/about_symbols.rb +35 -0
  369. data/solutions/about-to-str/about_to_str.rb +24 -0
  370. data/solutions/about-triangle-project/about_triangle_project.rb +19 -0
  371. data/solutions/about-triangle-project-two/about_triangle_project_two.rb +25 -0
  372. data/solutions/about-true-and-false/about_true_and_false.rb +25 -0
  373. data/solutions/blocks-and-methods/blocks_and_methods.rb +14 -0
  374. data/solutions/class-state/class_state.rb +33 -0
  375. data/solutions/closure-capture/closure_capture.rb +12 -0
  376. data/solutions/collection-basics/collection_basics.rb +14 -0
  377. data/solutions/constant-scope/constant_scope.rb +18 -0
  378. data/solutions/core-protocols/core_protocols.rb +44 -0
  379. data/solutions/delegation/delegation.rb +17 -0
  380. data/solutions/dynamic-methods/dynamic_methods.rb +32 -0
  381. data/solutions/exception-flow/exception_flow.rb +34 -0
  382. data/solutions/heredoc-layout/heredoc_layout.rb +24 -0
  383. data/solutions/keyword-forwarding/keyword_forwarding.rb +26 -0
  384. data/solutions/lazy-enumeration/lazy_enumeration.rb +11 -0
  385. data/solutions/literals-and-operators/literals_and_operators.rb +22 -0
  386. data/solutions/method-contracts/method_contracts.rb +18 -0
  387. data/solutions/method-lookup/method_lookup.rb +26 -0
  388. data/solutions/nonlocal-exit/nonlocal_exit.rb +46 -0
  389. data/solutions/numbered-parameters/numbered_parameters.rb +18 -0
  390. data/solutions/numeric-precision/numeric_precision.rb +17 -0
  391. data/solutions/pattern-matching/pattern_matching.rb +17 -0
  392. data/solutions/refinement-scope/refinement_scope.rb +34 -0
  393. data/solutions/regexp-captures/regexp_captures.rb +24 -0
  394. data/solutions/runtime-context/runtime_context.rb +19 -0
  395. data/solutions/shared-rows/shared_rows.rb +13 -0
  396. data/solutions/singleton-pattern/singleton_pattern.rb +19 -0
  397. data/solutions/time-and-date/time_and_date.rb +16 -0
  398. data/solutions/visibility/visibility.rb +34 -0
  399. data/test/exercises/about_array_assignment_test.rb +87 -0
  400. data/test/exercises/about_arrays_test.rb +119 -0
  401. data/test/exercises/about_asserts_test.rb +41 -0
  402. data/test/exercises/about_blocks_test.rb +140 -0
  403. data/test/exercises/about_class_methods_test.rb +232 -0
  404. data/test/exercises/about_classes_test.rb +261 -0
  405. data/test/exercises/about_constants_test.rb +111 -0
  406. data/test/exercises/about_control_statements_test.rb +188 -0
  407. data/test/exercises/about_dice_project_test.rb +40 -0
  408. data/test/exercises/about_exceptions_test.rb +98 -0
  409. data/test/exercises/about_extra_credit_test.rb +74 -0
  410. data/test/exercises/about_hashes_test.rb +163 -0
  411. data/test/exercises/about_inheritance_test.rb +121 -0
  412. data/test/exercises/about_iteration_test.rb +148 -0
  413. data/test/exercises/about_keyword_arguments_test.rb +80 -0
  414. data/test/exercises/about_message_passing_test.rb +230 -0
  415. data/test/exercises/about_methods_test.rb +208 -0
  416. data/test/exercises/about_modules_test.rb +98 -0
  417. data/test/exercises/about_nil_test.rb +35 -0
  418. data/test/exercises/about_objects_test.rb +74 -0
  419. data/test/exercises/about_open_classes_test.rb +60 -0
  420. data/test/exercises/about_pattern_matching_test.rb +257 -0
  421. data/test/exercises/about_proxy_object_project_test.rb +75 -0
  422. data/test/exercises/about_regular_expressions_test.rb +243 -0
  423. data/test/exercises/about_sandwich_code_test.rb +82 -0
  424. data/test/exercises/about_scope_test.rb +123 -0
  425. data/test/exercises/about_scoring_project_test.rb +62 -0
  426. data/test/exercises/about_strings_test.rb +255 -0
  427. data/test/exercises/about_symbols_test.rb +120 -0
  428. data/test/exercises/about_to_str_test.rb +89 -0
  429. data/test/exercises/about_triangle_project_test.rb +29 -0
  430. data/test/exercises/about_triangle_project_two_test.rb +28 -0
  431. data/test/exercises/about_true_and_false_test.rb +43 -0
  432. data/test/exercises/blocks_and_methods_test.rb +22 -0
  433. data/test/exercises/class_state_test.rb +29 -0
  434. data/test/exercises/closure_capture_test.rb +29 -0
  435. data/test/exercises/collection_basics_test.rb +18 -0
  436. data/test/exercises/constant_scope_test.rb +18 -0
  437. data/test/exercises/core_protocols_test.rb +28 -0
  438. data/test/exercises/delegation_test.rb +23 -0
  439. data/test/exercises/dynamic_methods_test.rb +28 -0
  440. data/test/exercises/exception_flow_test.rb +17 -0
  441. data/test/exercises/heredoc_layout_test.rb +18 -0
  442. data/test/exercises/keyword_forwarding_test.rb +22 -0
  443. data/test/exercises/lazy_enumeration_test.rb +15 -0
  444. data/test/exercises/literals_and_operators_test.rb +25 -0
  445. data/test/exercises/method_contracts_test.rb +28 -0
  446. data/test/exercises/method_lookup_test.rb +14 -0
  447. data/test/exercises/nonlocal_exit_test.rb +22 -0
  448. data/test/exercises/numbered_parameters_test.rb +15 -0
  449. data/test/exercises/numeric_precision_test.rb +24 -0
  450. data/test/exercises/pattern_matching_test.rb +18 -0
  451. data/test/exercises/refinement_scope_test.rb +14 -0
  452. data/test/exercises/regexp_captures_test.rb +20 -0
  453. data/test/exercises/runtime_context_test.rb +59 -0
  454. data/test/exercises/shared_rows_test.rb +34 -0
  455. data/test/exercises/singleton_pattern_test.rb +16 -0
  456. data/test/exercises/time_and_date_test.rb +22 -0
  457. data/test/exercises/visibility_test.rb +22 -0
  458. metadata +471 -4
  459. data/Rakefile +0 -12
  460. data/sig/test_rkoans.rbs +0 -3
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ # SPDX-License-Identifier: CC-BY-NC-SA-3.0
4
+ # Adapted from Ruby Koans by Jim Weirich and Joe O'Brien.
5
+ # See THIRD_PARTY_NOTICES.md for attribution and license terms.
6
+
7
+ module Exercises
8
+ # A set of dice with stable values until the next roll.
9
+ class AboutDiceProject
10
+ # Stores the latest roll from an injectable random source.
11
+ class DiceSet
12
+ attr_reader :values
13
+
14
+ # @param random [Random] source of uniform six-sided die values
15
+ def initialize(random: Random.new)
16
+ @random = random
17
+ @values = []
18
+ end
19
+
20
+ # @param count [Integer] number of dice to roll
21
+ # @return [Array<Integer>] freshly rolled values
22
+ def roll(_count)
23
+ @values = []
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,12 @@
1
+ # Dice Project
2
+
3
+ Complete `Exercises::AboutDiceProject::DiceSet#roll(count)` in `about_dice_project.rb`.
4
+ Replace `values` with exactly `count` integers from 1 through 6. Values must stay
5
+ stable when read and only change when rolled. Zero dice produces an empty array.
6
+ Use the random source supplied to the constructor and call `rand(1..6)` once
7
+ per die. Normal use defaults to `Random.new`; checks supply a seeded source.
8
+
9
+ Two genuinely random rolls can be equal. The checks therefore replay a known
10
+ random stream instead of requiring successive rolls to differ.
11
+
12
+ Adapted from Ruby Koans by Jim Weirich and Joe O'Brien, licensed under CC BY-NC-SA 3.0. See `THIRD_PARTY_NOTICES.md`.
@@ -0,0 +1,5 @@
1
+ # Hint
2
+
3
+ Build a fresh array on each roll and draw separately for each die. Do not draw when reading values.
4
+
5
+ Adapted from Ruby Koans by Jim Weirich and Joe O'Brien, licensed under CC BY-NC-SA 3.0. See `THIRD_PARTY_NOTICES.md`.
@@ -0,0 +1,84 @@
1
+ # frozen_string_literal: true
2
+
3
+ # SPDX-License-Identifier: CC-BY-NC-SA-3.0
4
+ # Adapted from Ruby Koans by Jim Weirich and Joe O'Brien.
5
+ # See THIRD_PARTY_NOTICES.md for attribution and license terms.
6
+
7
+ module Exercises
8
+ # Predictions for exceptions examples.
9
+ class AboutExceptions
10
+ # Replace each :fill_me_in with the result of the described expression.
11
+ # @return [Hash<Symbol, Object>]
12
+ # This method is an answer table, not a sequence of operations.
13
+ def self.koans
14
+ {
15
+ # Exceptions inherit from exception.
16
+ # assert_equal __, MySpecialError.ancestors[1]
17
+ # assert_equal __, MySpecialError.ancestors[2]
18
+ # assert_equal __, MySpecialError.ancestors[3]
19
+ # assert_equal __, MySpecialError.ancestors[4]
20
+ # Predict: MySpecialError.ancestors[1]
21
+ exceptions_inherit_from_Exception_one: :fill_me_in,
22
+ # Predict: MySpecialError.ancestors[2]
23
+ exceptions_inherit_from_Exception_two: :fill_me_in,
24
+ # Predict: MySpecialError.ancestors[3]
25
+ exceptions_inherit_from_Exception_three: :fill_me_in,
26
+ # Predict: MySpecialError.ancestors[4]
27
+ exceptions_inherit_from_Exception_four: :fill_me_in,
28
+ # Rescue clause.
29
+ # result = nil
30
+ # begin
31
+ # fail "Oops"
32
+ # rescue StandardError => ex
33
+ # result = :exception_handled
34
+ # end
35
+ # assert_equal __, result
36
+ # assert_equal __, ex.is_a?(StandardError), "Should be a Standard Error"
37
+ # assert_equal __, ex.is_a?(RuntimeError), "Should be a Runtime Error"
38
+ # assert RuntimeError.ancestors.include?(StandardError),
39
+ # "RuntimeError is a subclass of StandardError"
40
+ # assert_equal __, ex.message
41
+ # Predict: result
42
+ rescue_clause_one: :fill_me_in,
43
+ # Predict: ex.is_a?(StandardError)
44
+ rescue_clause_two: :fill_me_in,
45
+ # Predict: ex.is_a?(RuntimeError)
46
+ rescue_clause_three: :fill_me_in,
47
+ # Predict: ex.message
48
+ rescue_clause_four: :fill_me_in,
49
+ # Raising a particular error.
50
+ # result = nil
51
+ # begin
52
+ # 'raise' and 'fail' are synonyms
53
+ # raise MySpecialError, "My Message"
54
+ # rescue MySpecialError => ex
55
+ # result = :exception_handled
56
+ # end
57
+ # assert_equal __, result
58
+ # assert_equal __, ex.message
59
+ # Predict: result
60
+ raising_a_particular_error_one: :fill_me_in,
61
+ # Predict: ex.message
62
+ raising_a_particular_error_two: :fill_me_in,
63
+ # Ensure clause.
64
+ # result = nil
65
+ # begin
66
+ # fail "Oops"
67
+ # rescue StandardError
68
+ # no code here
69
+ # ensure
70
+ # result = :always_run
71
+ # end
72
+ # assert_equal __, result
73
+ # Predict: result
74
+ ensure_clause_one: :fill_me_in,
75
+ # Asserting an error is raised.
76
+ # assert_raise(___) do
77
+ # raise MySpecialError.new("New instances can be raised directly.")
78
+ # end
79
+ # Predict: exception class from: raise MySpecialError.new("New instances can be raised directly.")
80
+ asserting_an_error_is_raised_one: :fill_me_in
81
+ }
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,19 @@
1
+ # About Exceptions
2
+
3
+ Replace each `:fill_me_in` in `about_exceptions.rb` with the predicted result.
4
+ Each field identifies its example. Run the checks after edits to investigate the
5
+ next prediction. Answers include the Ruby values and exception classes shown by
6
+ the examples. Read the setup comments before evaluating an expression.
7
+
8
+ ## Example definitions
9
+
10
+ These definitions supply the objects and methods used by the prediction examples.
11
+ They run in the check class `AboutExceptionsTest`.
12
+
13
+ ```ruby
14
+ class MySpecialError < RuntimeError
15
+ end
16
+ ```
17
+
18
+ Adapted from Ruby Koans by Jim Weirich and Joe O'Brien, licensed under
19
+ CC BY-NC-SA 3.0. See `THIRD_PARTY_NOTICES.md` for attribution and license terms.
@@ -0,0 +1,8 @@
1
+ # Hint
2
+
3
+ Follow the raised exception through rescue and ensure. Inspect its class,
4
+ ancestors, and message. A rescue chooses compatible exception classes; ensure
5
+ runs even after an exception is handled.
6
+
7
+ Adapted from Ruby Koans by Jim Weirich and Joe O'Brien, licensed under
8
+ CC BY-NC-SA 3.0. See `THIRD_PARTY_NOTICES.md` for attribution and license terms.
@@ -0,0 +1,117 @@
1
+ # frozen_string_literal: true
2
+
3
+ # SPDX-License-Identifier: CC-BY-NC-SA-3.0
4
+ # Adapted from Ruby Koans by Jim Weirich and Joe O'Brien.
5
+ # See THIRD_PARTY_NOTICES.md for attribution and license terms.
6
+
7
+ module Exercises
8
+ # A deterministic Greed game engine; callers supply rolls and decide when to bank.
9
+ class AboutExtraCredit
10
+ # Tracks one player and the entry threshold.
11
+ class Player
12
+ attr_reader :name, :score
13
+
14
+ # @param name [String] player name
15
+ def initialize(name)
16
+ @name = name
17
+ @score = 0
18
+ end
19
+
20
+ # Bank a turn once the player has entered with at least 300 points.
21
+ # @return [Integer] total score
22
+ # TODO: require 300 points to enter the game.
23
+ def bank(points)
24
+ @score += points
25
+ @score
26
+ end
27
+ end
28
+
29
+ # Coordinates turn order, banking, busts and the final round.
30
+ class Game
31
+ attr_reader :players, :current
32
+
33
+ # @param names [Array<String>] at least two players, in turn order
34
+ def initialize(names)
35
+ raise ArgumentError, 'at least two players required' if names.size < 2
36
+
37
+ @players = names.map { |name| Player.new(name) }
38
+ @current = 0
39
+ @remaining = nil
40
+ end
41
+
42
+ # Play the current player's complete turn; ending the rolls banks the points.
43
+ # @param rolls [Array<Array<Integer>>] ordered rolls, with legal remaining-dice counts
44
+ # @return [Integer] that player's total score after this turn
45
+ def play_turn(rolls)
46
+ raise 'game finished' if finished?
47
+
48
+ total = players[current].bank(turn_points(rolls))
49
+ advance(total)
50
+ total
51
+ end
52
+
53
+ # @return [Boolean] all other players have taken their final turn
54
+ def finished?
55
+ @remaining&.zero? || false
56
+ end
57
+
58
+ # @return [Player, nil] highest-scoring player after the final round; first in a tie
59
+ def winner
60
+ players.max_by(&:score) if finished?
61
+ end
62
+
63
+ private
64
+
65
+ # @return [Integer] accumulated turn points, or zero after a bust
66
+ def turn_points(rolls)
67
+ raise ArgumentError, 'a turn needs at least one roll' if rolls.empty?
68
+
69
+ points = 0
70
+ count = 5
71
+ rolls.each_with_index do |roll, index|
72
+ validate_roll(roll, count)
73
+ scored, unused = score_roll(roll)
74
+ if scored.zero?
75
+ raise ArgumentError, 'turn ends on a bust' unless index == rolls.size - 1
76
+
77
+ # TODO: a bust loses all points from this turn.
78
+ return points
79
+ end
80
+ points += scored
81
+ count = unused.zero? ? 5 : unused
82
+ end
83
+ points
84
+ end
85
+
86
+ # @return [void] reject malformed rolls before changing game state
87
+ def validate_roll(roll, count)
88
+ valid = roll.size == count && roll.all? { |face| face.is_a?(Integer) && (1..6).cover?(face) }
89
+ raise ArgumentError, 'invalid dice count or face' unless valid
90
+ end
91
+
92
+ # @return [Array<Integer>] points and the number of non-scoring dice
93
+ def score_roll(roll)
94
+ points = 0
95
+ unused = 0
96
+ roll.tally.each do |face, amount|
97
+ triples, singles = amount.divmod(3)
98
+ points += triples * (face == 1 ? 1000 : face * 100)
99
+ points += singles * { 1 => 100, 5 => 50 }.fetch(face, 0)
100
+ unused += singles unless [1, 5].include?(face)
101
+ end
102
+ [points, unused]
103
+ end
104
+
105
+ # Start the final round once, then give each remaining player exactly one turn.
106
+ def advance(total)
107
+ if @remaining
108
+ @remaining -= 1
109
+ elsif total >= 3000
110
+ # TODO: the other players still get a final turn.
111
+ @remaining = 0
112
+ end
113
+ @current = (current + 1) % players.size
114
+ end
115
+ end
116
+ end
117
+ end
@@ -0,0 +1,28 @@
1
+ # Extra Credit
2
+
3
+ The original extra-credit chapter proposes a free-form Greed game. This adaptation
4
+ provides a deterministic engine to repair in `about_extra_credit.rb`; a terminal
5
+ interface or computer player remains an optional extension.
6
+
7
+ Fix the three incomplete rules in `Player#bank`, `Game#turn_points`, and
8
+ `Game#advance`. Supplied scoring follows the scoring project: triples of ones
9
+ are 1000, other triples are 100 times the face, remaining ones are 100 and
10
+ fives are 50. Dice count once per roll.
11
+
12
+ `Game.new(names)` requires at least two players. `play_turn(rolls)` accepts all
13
+ rolls for the current player and returns their total score. The first roll uses
14
+ five dice; later rolls use only non-scoring dice, or five again when all scored.
15
+ Ending the supplied rolls means banking. A zero-point roll ends the turn and
16
+ loses its accumulated points, preserving earlier banked totals. A player must
17
+ first bank at least 300 in one turn; smaller turns count after entry.
18
+
19
+ Reaching 3000 starts the final round: every other player gets exactly one more
20
+ turn, even if someone overtakes the leader. `finished?` then becomes true and
21
+ `winner` returns the highest-scoring Player (first in turn order on a tie).
22
+ Reject further turns. Malformed rolls raise `ArgumentError` without advancing
23
+ the game. Example: `[[1, 5, 2, 3, 4], [2, 2, 2]]` banks 350 points.
24
+
25
+ Rolls are inputs so the game can be checked reproducibly. You can connect it to
26
+ your DiceSet and a human or automated decision-maker as an optional extension.
27
+
28
+ Adapted from Ruby Koans by Jim Weirich and Joe O'Brien, licensed under CC BY-NC-SA 3.0. See `THIRD_PARTY_NOTICES.md`.
@@ -0,0 +1,5 @@
1
+ # Hint
2
+
3
+ Keep turn points separate from banked scores. Start a final-turn countdown only once; do not restart it when another player reaches 3000.
4
+
5
+ Adapted from Ruby Koans by Jim Weirich and Joe O'Brien, licensed under CC BY-NC-SA 3.0. See `THIRD_PARTY_NOTICES.md`.
@@ -0,0 +1,160 @@
1
+ # frozen_string_literal: true
2
+
3
+ # SPDX-License-Identifier: CC-BY-NC-SA-3.0
4
+ # Adapted from Ruby Koans by Jim Weirich and Joe O'Brien.
5
+ # See THIRD_PARTY_NOTICES.md for attribution and license terms.
6
+
7
+ module Exercises
8
+ # Predictions for hashes examples.
9
+ class AboutHashes
10
+ # Replace each :fill_me_in with the result of the described expression.
11
+ # @return [Hash<Symbol, Object>]
12
+ # This method is an answer table, not a sequence of operations.
13
+ def self.koans # rubocop:disable Metrics/MethodLength
14
+ {
15
+ # Creating hashes.
16
+ # empty_hash = Hash.new
17
+ # assert_equal __, empty_hash.class
18
+ # assert_equal(__, empty_hash)
19
+ # assert_equal __, empty_hash.size
20
+ # Predict: empty_hash.class
21
+ creating_hashes_one: :fill_me_in,
22
+ # Predict: empty_hash
23
+ creating_hashes_two: :fill_me_in,
24
+ # Predict: empty_hash.size
25
+ creating_hashes_three: :fill_me_in,
26
+ # Hash literals.
27
+ # hash = { :one => "uno", :two => "dos" }
28
+ # assert_equal __, hash.size
29
+ # Predict: hash.size
30
+ hash_literals_one: :fill_me_in,
31
+ # Accessing hashes.
32
+ # hash = { :one => "uno", :two => "dos" }
33
+ # assert_equal __, hash[:one]
34
+ # assert_equal __, hash[:two]
35
+ # assert_equal __, hash[:doesnt_exist]
36
+ # Predict: hash[:one]
37
+ accessing_hashes_one: :fill_me_in,
38
+ # Predict: hash[:two]
39
+ accessing_hashes_two: :fill_me_in,
40
+ # Predict: hash[:doesnt_exist]
41
+ accessing_hashes_three: :fill_me_in,
42
+ # Accessing hashes with fetch.
43
+ # hash = { :one => "uno" }
44
+ # assert_equal __, hash.fetch(:one)
45
+ # assert_raise(___) do
46
+ # hash.fetch(:doesnt_exist)
47
+ # end
48
+ # Predict: hash.fetch(:one)
49
+ accessing_hashes_with_fetch_one: :fill_me_in,
50
+ # Predict: exception class from: hash.fetch(:doesnt_exist)
51
+ accessing_hashes_with_fetch_two: :fill_me_in,
52
+ # Changing hashes.
53
+ # hash = { :one => "uno", :two => "dos" }
54
+ # hash[:one] = "eins"
55
+ # assert_equal __, hash
56
+ # Predict: hash
57
+ changing_hashes_one: :fill_me_in,
58
+ # Hash is unordered.
59
+ # hash1 = { :one => "uno", :two => "dos" }
60
+ # hash2 = { :two => "dos", :one => "uno" }
61
+ # assert_equal __, hash1 == hash2
62
+ # Predict: hash1 == hash2
63
+ hash_is_unordered_one: :fill_me_in,
64
+ # Hash keys.
65
+ # hash = { :one => "uno", :two => "dos" }
66
+ # assert_equal __, hash.keys.size
67
+ # assert_equal __, hash.keys.include?(:one)
68
+ # assert_equal __, hash.keys.include?(:two)
69
+ # assert_equal __, hash.keys.class
70
+ # Predict: hash.keys.size
71
+ hash_keys_one: :fill_me_in,
72
+ # Predict: hash.keys.include?(:one)
73
+ hash_keys_two: :fill_me_in,
74
+ # Predict: hash.keys.include?(:two)
75
+ hash_keys_three: :fill_me_in,
76
+ # Predict: hash.keys.class
77
+ hash_keys_four: :fill_me_in,
78
+ # Hash values.
79
+ # hash = { :one => "uno", :two => "dos" }
80
+ # assert_equal __, hash.values.size
81
+ # assert_equal __, hash.values.include?("uno")
82
+ # assert_equal __, hash.values.include?("dos")
83
+ # assert_equal __, hash.values.class
84
+ # Predict: hash.values.size
85
+ hash_values_one: :fill_me_in,
86
+ # Predict: hash.values.include?("uno")
87
+ hash_values_two: :fill_me_in,
88
+ # Predict: hash.values.include?("dos")
89
+ hash_values_three: :fill_me_in,
90
+ # Predict: hash.values.class
91
+ hash_values_four: :fill_me_in,
92
+ # Combining hashes.
93
+ # hash = { "jim" => 53, "amy" => 20, "dan" => 23 }
94
+ # new_hash = hash.merge({ "jim" => 54, "jenny" => 26 })
95
+ # assert_equal __, hash != new_hash
96
+ # expected = { "jim" => 54, "amy" => 20, "dan" => 23, "jenny" => 26 }
97
+ # assert_equal __, expected == new_hash
98
+ # Predict: hash != new_hash
99
+ combining_hashes_one: :fill_me_in,
100
+ # Predict: expected == new_hash
101
+ combining_hashes_two: :fill_me_in,
102
+ # Default value.
103
+ # hash1 = Hash.new
104
+ # hash1[:one] = 1
105
+ # assert_equal __, hash1[:one]
106
+ # assert_equal __, hash1[:two]
107
+ # hash2 = Hash.new("dos")
108
+ # hash2[:one] = 1
109
+ # assert_equal __, hash2[:one]
110
+ # assert_equal __, hash2[:two]
111
+ # Predict: hash1[:one]
112
+ default_value_one: :fill_me_in,
113
+ # Predict: hash1[:two]
114
+ default_value_two: :fill_me_in,
115
+ # Predict: hash2[:one]
116
+ default_value_three: :fill_me_in,
117
+ # Predict: hash2[:two]
118
+ default_value_four: :fill_me_in,
119
+ # Default value is the same object.
120
+ # hash = Hash.new([])
121
+ # hash[:one] << "uno"
122
+ # hash[:two] << "dos"
123
+ # assert_equal __, hash[:one]
124
+ # assert_equal __, hash[:two]
125
+ # assert_equal __, hash[:three]
126
+ # assert_equal __, hash[:one].equal?(hash[:two])
127
+ # Predict: hash[:one]
128
+ default_value_is_the_same_object_one: :fill_me_in,
129
+ # Predict: hash[:two]
130
+ default_value_is_the_same_object_two: :fill_me_in,
131
+ # Predict: hash[:three]
132
+ default_value_is_the_same_object_three: :fill_me_in,
133
+ # Predict: hash[:one].equal?(hash[:two])
134
+ default_value_is_the_same_object_four: :fill_me_in,
135
+ # Default value with block.
136
+ # hash = Hash.new {|hash, key| hash[key] = [] }
137
+ # hash[:one] << "uno"
138
+ # hash[:two] << "dos"
139
+ # assert_equal __, hash[:one]
140
+ # assert_equal __, hash[:two]
141
+ # assert_equal __, hash[:three]
142
+ # Predict: hash[:one]
143
+ default_value_with_block_one: :fill_me_in,
144
+ # Predict: hash[:two]
145
+ default_value_with_block_two: :fill_me_in,
146
+ # Predict: hash[:three]
147
+ default_value_with_block_three: :fill_me_in,
148
+ # Default value attribute.
149
+ # hash = Hash.new
150
+ # assert_equal __, hash[:some_key]
151
+ # hash.default = 'peanut'
152
+ # assert_equal __, hash[:some_key]
153
+ # Predict: hash[:some_key]
154
+ default_value_attribute_one: :fill_me_in,
155
+ # Predict: hash[:some_key]
156
+ default_value_attribute_two: :fill_me_in
157
+ }
158
+ end
159
+ end
160
+ end
@@ -0,0 +1,9 @@
1
+ # About Hashes
2
+
3
+ Replace each `:fill_me_in` in `about_hashes.rb` with the predicted result.
4
+ Each field identifies its example. Run the checks after edits to investigate the
5
+ next prediction. Answers include the Ruby values and exception classes shown by
6
+ the examples. Read the setup comments before evaluating an expression.
7
+
8
+ Adapted from Ruby Koans by Jim Weirich and Joe O'Brien, licensed under
9
+ CC BY-NC-SA 3.0. See `THIRD_PARTY_NOTICES.md` for attribution and license terms.
@@ -0,0 +1,8 @@
1
+ # Hint
2
+
3
+ Compare `hash[key]` with `hash.fetch(key)` for an absent key.
4
+ A shared default object is reused; a default block can create and store a fresh
5
+ value for each key. Merging returns a new hash; inspect both hashes afterward.
6
+
7
+ Adapted from Ruby Koans by Jim Weirich and Joe O'Brien, licensed under
8
+ CC BY-NC-SA 3.0. See `THIRD_PARTY_NOTICES.md` for attribution and license terms.
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ # SPDX-License-Identifier: CC-BY-NC-SA-3.0
4
+ # Adapted from Ruby Koans by Jim Weirich and Joe O'Brien.
5
+ # See THIRD_PARTY_NOTICES.md for attribution and license terms.
6
+
7
+ module Exercises
8
+ # Predictions for inheritance examples.
9
+ class AboutInheritance
10
+ # Replace each :fill_me_in with the result of the described expression.
11
+ # @return [Hash<Symbol, Object>]
12
+ # This method is an answer table, not a sequence of operations.
13
+ def self.koans
14
+ {
15
+ # Subclasses have the parent as an ancestor.
16
+ # assert_equal __, Chihuahua.ancestors.include?(Dog)
17
+ # Predict: Chihuahua.ancestors.include?(Dog)
18
+ subclasses_have_the_parent_as_an_ancestor_one: :fill_me_in,
19
+ # All classes ultimately inherit from object.
20
+ # assert_equal __, Chihuahua.ancestors.include?(Object)
21
+ # Predict: Chihuahua.ancestors.include?(Object)
22
+ all_classes_ultimately_inherit_from_object_one: :fill_me_in,
23
+ # Subclasses inherit behavior from parent class.
24
+ # chico = Chihuahua.new("Chico")
25
+ # assert_equal __, chico.name
26
+ # Predict: chico.name
27
+ subclasses_inherit_behavior_from_parent_class_one: :fill_me_in,
28
+ # Subclasses add new behavior.
29
+ # chico = Chihuahua.new("Chico")
30
+ # assert_equal __, chico.wag
31
+ # assert_raise(___) do
32
+ # fido = Dog.new("Fido")
33
+ # fido.wag
34
+ # end
35
+ # Predict: chico.wag
36
+ subclasses_add_new_behavior_one: :fill_me_in,
37
+ # Predict: exception class from: fido = Dog.new("Fido"); fido.wag
38
+ subclasses_add_new_behavior_two: :fill_me_in,
39
+ # Subclasses can modify existing behavior.
40
+ # chico = Chihuahua.new("Chico")
41
+ # assert_equal __, chico.bark
42
+ # fido = Dog.new("Fido")
43
+ # assert_equal __, fido.bark
44
+ # Predict: chico.bark
45
+ subclasses_can_modify_existing_behavior_one: :fill_me_in,
46
+ # Predict: fido.bark
47
+ subclasses_can_modify_existing_behavior_two: :fill_me_in,
48
+ # Subclasses can invoke parent behavior via super.
49
+ # ralph = BullDog.new("Ralph")
50
+ # assert_equal __, ralph.bark
51
+ # Predict: ralph.bark
52
+ subclasses_can_invoke_parent_behavior_via_super_one: :fill_me_in,
53
+ # Super does not work cross method.
54
+ # george = GreatDane.new("George")
55
+ # assert_raise(___) do
56
+ # george.growl
57
+ # end
58
+ # Predict: exception class from: george.growl
59
+ super_does_not_work_cross_method_one: :fill_me_in
60
+ }
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,50 @@
1
+ # About Inheritance
2
+
3
+ Replace each `:fill_me_in` in `about_inheritance.rb` with the predicted result.
4
+ Each field identifies its example. Run the checks after edits to investigate the
5
+ next prediction. Answers include the Ruby values and exception classes shown by
6
+ the examples. Read the setup comments before evaluating an expression.
7
+
8
+ ## Example definitions
9
+
10
+ These definitions supply the objects and methods used by the prediction examples.
11
+ They run in the check class `AboutInheritanceTest`.
12
+
13
+ ```ruby
14
+ class Dog
15
+ attr_reader :name
16
+
17
+ def initialize(name)
18
+ @name = name
19
+ end
20
+
21
+ def bark
22
+ "WOOF"
23
+ end
24
+ end
25
+
26
+ class Chihuahua < Dog
27
+ def wag
28
+ :happy
29
+ end
30
+
31
+ def bark
32
+ "yip"
33
+ end
34
+ end
35
+
36
+ class BullDog < Dog
37
+ def bark
38
+ super + ", GROWL"
39
+ end
40
+ end
41
+
42
+ class GreatDane < Dog
43
+ def growl
44
+ super.bark + ", GROWL"
45
+ end
46
+ end
47
+ ```
48
+
49
+ Adapted from Ruby Koans by Jim Weirich and Joe O'Brien, licensed under
50
+ CC BY-NC-SA 3.0. See `THIRD_PARTY_NOTICES.md` for attribution and license terms.
@@ -0,0 +1,8 @@
1
+ # Hint
2
+
3
+ Look at the receiver class and its ancestors. `super` invokes the same method
4
+ name further up the lookup chain; it does not search for a differently named
5
+ method on the parent.
6
+
7
+ Adapted from Ruby Koans by Jim Weirich and Joe O'Brien, licensed under
8
+ CC BY-NC-SA 3.0. See `THIRD_PARTY_NOTICES.md` for attribution and license terms.