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,21 @@
1
+ # Symbols: names, values, and identity
2
+
3
+ Replace each `:fill_me_in` prediction with the result of its commented example.
4
+ Use `true` or `false` for comparisons, symbols or strings for converted values,
5
+ and an exception class for the unsupported concatenation example.
6
+
7
+ Compare the value and identity of two symbols with the same name. Convert a
8
+ string to a symbol, try quoted names containing spaces, and observe interpolation.
9
+ A symbol is a different type from a string, even when they have the same spelling.
10
+
11
+ The checks define a constant named `RUBY_CONSTANT` and a method named
12
+ `test_method_names_become_symbols`. Predict whether their names occur in
13
+ `Symbol.all_symbols`. Compare strings when searching: creating a new symbol for
14
+ the expected name would change the table being observed.
15
+
16
+ For `concatenation_error`, predict the class of the exception raised by
17
+ `:cats + :dogs`, rather than an exception instance. Save a group of predictions
18
+ at a time and compare Expected (your prediction) with Actual (Ruby's result).
19
+
20
+ Adapted from **Ruby Koans: About Symbols** by Jim Weirich and Joe O'Brien.
21
+ Licensed under [CC BY-NC-SA 3.0](https://creativecommons.org/licenses/by-nc-sa/3.0/).
@@ -0,0 +1,12 @@
1
+ # Hint: a symbol is a name, not a string
2
+
3
+ Identical symbol names refer to the same symbol object. `to_sym` converts a
4
+ string into a symbol, while interpolation uses `to_s` to insert text.
5
+
6
+ Use `respond_to?` to explore a proposed string operation. If an operation is
7
+ unsupported, Ruby's failure names the exception class; compare that class with
8
+ your prediction. Constant and method names already declared by the checks are
9
+ present in the symbol table.
10
+
11
+ Adapted from **Ruby Koans: About Symbols** by Jim Weirich and Joe O'Brien.
12
+ Licensed under [CC BY-NC-SA 3.0](https://creativecommons.org/licenses/by-nc-sa/3.0/).
@@ -0,0 +1,49 @@
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 to str examples.
9
+ class AboutToStr
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
+ # To s returns a string representation.
16
+ # not_like_a_string = CanNotBeTreatedAsString.new
17
+ # assert_equal __, not_like_a_string.to_s
18
+ # Predict: not_like_a_string.to_s
19
+ to_s_returns_a_string_representation_one: :fill_me_in,
20
+ # Normally objects cannot be used where strings are expected.
21
+ # assert_raise(___) do
22
+ # File.exist?(CanNotBeTreatedAsString.new)
23
+ # end
24
+ # Predict: exception class from: File.exist?(CanNotBeTreatedAsString.new)
25
+ normally_objects_cannot_be_used_where_strings_are_expected_one: :fill_me_in,
26
+ # To str also returns a string representation.
27
+ # like_a_string = CanBeTreatedAsString.new
28
+ # assert_equal __, like_a_string.to_str
29
+ # Predict: like_a_string.to_str
30
+ to_str_also_returns_a_string_representation_one: :fill_me_in,
31
+ # To str allows objects to be treated as strings.
32
+ # Dir.mktmpdir do |directory|
33
+ # Dir.chdir(directory) do
34
+ # assert_equal __, File.exist?(CanBeTreatedAsString.new)
35
+ # end
36
+ # end
37
+ # Predict: File.exist?(CanBeTreatedAsString.new)
38
+ to_str_allows_objects_to_be_treated_as_strings_one: :fill_me_in,
39
+ # User defined code can check for to str.
40
+ # assert_equal __, acts_like_a_string?(CanNotBeTreatedAsString.new)
41
+ # assert_equal __, acts_like_a_string?(CanBeTreatedAsString.new)
42
+ # Predict: acts_like_a_string?(CanNotBeTreatedAsString.new)
43
+ user_defined_code_can_check_for_to_str_one: :fill_me_in,
44
+ # Predict: acts_like_a_string?(CanBeTreatedAsString.new)
45
+ user_defined_code_can_check_for_to_str_two: :fill_me_in
46
+ }
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,37 @@
1
+ # About To Str
2
+
3
+ Replace each `:fill_me_in` in `about_to_str.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 `AboutToStrTest`.
12
+
13
+ ```ruby
14
+ class CanNotBeTreatedAsString
15
+ def to_s
16
+ "non-string-like"
17
+ end
18
+ end
19
+
20
+ class CanBeTreatedAsString
21
+ def to_s
22
+ "string-like"
23
+ end
24
+
25
+ def to_str
26
+ to_s
27
+ end
28
+ end
29
+
30
+ def acts_like_a_string?(string)
31
+ string = string.to_str if string.respond_to?(:to_str)
32
+ string.is_a?(String)
33
+ end
34
+ ```
35
+
36
+ Adapted from Ruby Koans by Jim Weirich and Joe O'Brien, licensed under
37
+ CC BY-NC-SA 3.0. See `THIRD_PARTY_NOTICES.md` for attribution and license terms.
@@ -0,0 +1,7 @@
1
+ # Hint
2
+
3
+ `to_s` gives an explicit representation. `to_str` opts an object into
4
+ implicit string conversion. An object may implement one without the other.
5
+
6
+ Adapted from Ruby Koans by Jim Weirich and Joe O'Brien, licensed under
7
+ CC BY-NC-SA 3.0. See `THIRD_PARTY_NOTICES.md` for attribution and license terms.
@@ -0,0 +1,15 @@
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
+ # Classifies triangles by the number of equal sides.
9
+ class AboutTriangleProject
10
+ # @return [Symbol] :equilateral, :isosceles, or :scalene for valid side lengths
11
+ def self.triangle(_side_a, _side_b, _side_c)
12
+ :fill_me_in
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,11 @@
1
+ # Triangle Project
2
+
3
+ Implement `Exercises::AboutTriangleProject.triangle(a, b, c)` in `about_triangle_project.rb`.
4
+ Return `:equilateral` for three equal sides, `:isosceles` for exactly two equal
5
+ sides, and `:scalene` otherwise. This first project accepts valid triangles;
6
+ handling invalid lengths comes after the exceptions lesson.
7
+
8
+ Run `rkoans check` after editing. Each project is self-contained; it does not
9
+ read or overwrite another exercise's learner file.
10
+
11
+ 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
+ Compare the number of distinct side lengths. Check every position of an equal pair.
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,22 @@
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
+ # Adds exception handling to triangle classification.
9
+ class AboutTriangleProjectTwo
10
+ class TriangleError < StandardError; end
11
+
12
+ # @raise [TriangleError] nonpositive or degenerate side lengths
13
+ # @return [Symbol] triangle classification
14
+ def self.triangle(side_a, side_b, side_c)
15
+ case [side_a, side_b, side_c].uniq.size
16
+ when 1 then :equilateral
17
+ when 2 then :isosceles
18
+ else :scalene
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,10 @@
1
+ # Triangle Project Two
2
+
3
+ Add validation to `Exercises::AboutTriangleProjectTwo.triangle` in
4
+ `about_triangle_project_two.rb`. Raise its nested `TriangleError` if any side
5
+ is zero or negative, or if two sides together are no longer than the third.
6
+ Retain the three valid classifications from part one. Numeric side lengths
7
+ may include fractions. A starting classifier is supplied here so this lesson
8
+ works independently of your saved part-one solution.
9
+
10
+ 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
+ Sort the sides before comparing the longest with the sum of the other two. Equality is invalid too.
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,26 @@
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
+ # Predicts the branch taken by Ruby's conditionals for common values.
9
+ class AboutTrueAndFalse
10
+ # Replace each nil with :true_stuff or :false_stuff.
11
+ # @return [Hash<Symbol, Symbol | nil>] expected branch labels for each input
12
+ def self.koans
13
+ {
14
+ true_value: nil,
15
+ false_value: nil,
16
+ nil_value: nil,
17
+ one: nil,
18
+ zero: nil,
19
+ empty_array: nil,
20
+ empty_hash: nil,
21
+ string: nil,
22
+ empty_string: nil
23
+ }
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,22 @@
1
+ # True, false, and everything else
2
+
3
+ An `if` statement chooses a branch based on its condition:
4
+
5
+ ```ruby
6
+ if condition
7
+ :true_stuff
8
+ else
9
+ :false_stuff
10
+ end
11
+ ```
12
+
13
+ Fill each answer in `koans` with `:true_stuff` or `:false_stuff`, predicting the
14
+ branch for `true`, `false`, `nil`, `1`, `0`, `[]`, `{}`, `"Strings"`, and `""`.
15
+ The answer names match these inputs in order. The colon creates a symbol, which
16
+ we use here as a branch label.
17
+
18
+ Pay particular attention to zero and empty collections. Do they behave like
19
+ false? Save one prediction at a time and read the failing check's message.
20
+
21
+ Adapted from **Ruby Koans: About True and False** by Jim Weirich and Joe O'Brien.
22
+ Licensed under [CC BY-NC-SA 3.0](https://creativecommons.org/licenses/by-nc-sa/3.0/).
@@ -0,0 +1,7 @@
1
+ # Hint: only two falsey values
2
+
3
+ Ruby treats only `false` and `nil` as falsey. Zero, empty strings, empty arrays,
4
+ and empty hashes are truthy. Choose the branch label for each input.
5
+
6
+ Adapted from **Ruby Koans: About True and False** by Jim Weirich and Joe O'Brien.
7
+ Licensed under [CC BY-NC-SA 3.0](https://creativecommons.org/licenses/by-nc-sa/3.0/).
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Exercises
4
+ # Fill the expectation and implement the block invocation below.
5
+ class BlocksAndMethods
6
+ def self.koans
7
+ { sequence: nil }
8
+ end
9
+
10
+ def self.apply(value)
11
+ value
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,8 @@
1
+ # Who calls the block?
2
+
3
+ The expression `3.times.map { |i| i + 1 }` returns three values.
4
+ Fill `koans[:sequence]`. Implement `apply(value)` to call the supplied block
5
+ once and return its result. For `apply(5) { |n| n * 3 }`, return 15.
6
+ Calling without a block should raise `LocalJumpError`.
7
+
8
+ Save your file to rerun the checks automatically.
@@ -0,0 +1,6 @@
1
+ # Hint: calling a block
2
+
3
+ A block is behavior supplied by the caller, not an ordinary positional argument.
4
+ Ruby's `yield` invokes the block and returns its result.
5
+
6
+ For the expectation blank, work through the three values of `i` in `3.times`.
@@ -0,0 +1,61 @@
1
+ [
2
+ "about-asserts",
3
+ "about-true-and-false",
4
+ "about-strings",
5
+ "heredoc-layout",
6
+ "about-symbols",
7
+ "about-arrays",
8
+ "about-array-assignment",
9
+ "shared-rows",
10
+ "about-objects",
11
+ "about-nil",
12
+ "about-hashes",
13
+ "literals-and-operators",
14
+ "about-methods",
15
+ "numeric-precision",
16
+ "about-keyword-arguments",
17
+ "about-constants",
18
+ "about-regular-expressions",
19
+ "regexp-captures",
20
+ "about-control-statements",
21
+ "about-pattern-matching",
22
+ "pattern-matching",
23
+ "about-triangle-project",
24
+ "about-exceptions",
25
+ "exception-flow",
26
+ "about-triangle-project-two",
27
+ "about-iteration",
28
+ "about-blocks",
29
+ "collection-basics",
30
+ "blocks-and-methods",
31
+ "numbered-parameters",
32
+ "lazy-enumeration",
33
+ "closure-capture",
34
+ "nonlocal-exit",
35
+ "method-contracts",
36
+ "keyword-forwarding",
37
+ "about-sandwich-code",
38
+ "about-scoring-project",
39
+ "about-classes",
40
+ "visibility",
41
+ "about-open-classes",
42
+ "about-dice-project",
43
+ "about-inheritance",
44
+ "class-state",
45
+ "about-modules",
46
+ "core-protocols",
47
+ "about-scope",
48
+ "constant-scope",
49
+ "about-class-methods",
50
+ "singleton-pattern",
51
+ "method-lookup",
52
+ "about-message-passing",
53
+ "delegation",
54
+ "about-proxy-object-project",
55
+ "dynamic-methods",
56
+ "about-to-str",
57
+ "refinement-scope",
58
+ "time-and-date",
59
+ "runtime-context",
60
+ "about-extra-credit"
61
+ ]
@@ -0,0 +1,8 @@
1
+ # An inherited counter
2
+
3
+ Keep independent counts for Parent and Child. Both start at zero; incrementing one must not alter the other. Child.label must compose its label with Parent.label through super, producing "parent-child". Implement `singleton_owner` to identify the singleton class that owns Parent.label.
4
+
5
+ Use `rkoans check` to investigate one failing check at a time. Hints are optional.
6
+
7
+ Edit `class_state.rb` in this exercise's folder. Checks call
8
+ `Exercises::ClassState` and its example classes.
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Shared class variables are the deliberate starting bug.
4
+ # rubocop:disable Style/ClassVars
5
+
6
+ module Exercises
7
+ # Keep independent counts for Parent and Child.
8
+ class ClassState
9
+ # Example Parent for class state.
10
+ class Parent
11
+ @@count = 0
12
+ # Resets state belonging to this class object.
13
+ # @return [Integer]
14
+ def self.reset = @@count = 0
15
+ # Returns this class object's counter, defaulting to zero.
16
+ # @return [Integer]
17
+ def self.count = @@count
18
+ # Increments this class object's counter.
19
+ # @return [Integer]
20
+ def self.increment = @@count += 1
21
+ # Returns the label supplied by this class's inheritance chain.
22
+ # @return [String]
23
+ def self.label = 'parent'
24
+ end
25
+
26
+ # Example Child for class state.
27
+ class Child < Parent
28
+ # Returns the label supplied by this class's inheritance chain.
29
+ # @return [String]
30
+ def self.label = 'child'
31
+ end
32
+
33
+ # Returns the singleton class owning the label class method.
34
+ # @return [Class]
35
+ def self.singleton_owner = Parent
36
+ end
37
+ end
38
+
39
+ # rubocop:enable Style/ClassVars
@@ -0,0 +1,5 @@
1
+ # Hint
2
+
3
+ Class variables can share one slot through an inheritance hierarchy.
4
+
5
+ Class instance variables belong to each class object; initialize or default them per receiver.
@@ -0,0 +1,8 @@
1
+ # Three multipliers, one captured name
2
+
3
+ Implement `multipliers(numbers)` returning one lambda per number. Each lambda multiplies its single argument by its own captured number and rejects extra arguments. The starting for loop shares its loop variable, and Proc has different argument handling from lambda.
4
+
5
+ Use `rkoans check` to investigate one failing check at a time. Hints are optional.
6
+
7
+ Edit `closure_capture.rb` in this exercise's folder. Checks call
8
+ `Exercises::ClosureCapture` and its example classes.
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ # The example deliberately uses for rather than a block iterator.
4
+ # rubocop:disable Style/For
5
+
6
+ module Exercises
7
+ # Implement multipliers(numbers) returning one lambda per number.
8
+ class ClosureCapture
9
+ # Creates an independently captured lambda for each factor.
10
+ # @return [Array<Proc>]
11
+ def self.multipliers(numbers)
12
+ functions = []
13
+ for factor in numbers
14
+ functions << proc { |value| value * factor }
15
+ end
16
+ functions
17
+ end
18
+ end
19
+ end
20
+
21
+ # rubocop:enable Style/For
@@ -0,0 +1,5 @@
1
+ # Hint
2
+
3
+ A closure retains a variable, not just a snapshot of its current value.
4
+
5
+ A for loop shares its variable; an each block gives a useful scope for creating each closure.
@@ -0,0 +1,8 @@
1
+ # A collection of clues
2
+
3
+ Read `[1, 2, 3].map { |n| n * 2 }` and `[1, 2, 3].select(&:odd?)`.
4
+ Fill the two expectation blanks in `koans`, then implement `double_odds`
5
+ so it doubles only odd input numbers. For `[1, 2, 3]`, return `[2, 6]`.
6
+ Preserve the input array.
7
+
8
+ Save your file to rerun the checks automatically.
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Exercises
4
+ # Fill the expectations and implement the collection operation below.
5
+ class CollectionBasics
6
+ def self.koans
7
+ { mapped: nil, selected: nil }
8
+ end
9
+
10
+ # @param [Object] numbers
11
+ # @return [Object]
12
+ def self.double_odds(numbers)
13
+ numbers.map { |number| number * 2 }
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,6 @@
1
+ # Hint: choosing and transforming values
2
+
3
+ map returns one result for every input item; select keeps only matching items.
4
+ Separate choosing odd values from doubling those values.
5
+
6
+ For the expectation blanks, work through each input number and write the resulting arrays.
@@ -0,0 +1,8 @@
1
+ # Which scope owns this name?
2
+
3
+ Study this setup, then fill `predictions`: a module Catalog has LABEL="outer"; Catalog::Item has LABEL="item" and Catalog::Item::Nested reads LABEL. A class Base sets @@count=0; Child inherits Base and increments @@count. A local `value` assigned only inside a block does not become available outside that block unless it was already declared. Return lexical_label, shared_class_count, new_block_local_visible. Implement `counter` as a closure over a local integer; two separately created counters must not share state.
4
+
5
+ Use `rkoans check` to investigate one failing check at a time. Hints are optional.
6
+
7
+ Edit `constant_scope.rb` in this exercise's folder. Checks call
8
+ `Exercises::ConstantScope` and its example classes.
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Exercises
4
+ # Study this setup, then fill predictions: a module Catalog has LABEL="outer"; Catalog::Item has
5
+ # LABEL="item" and Catalog::Item::Nested reads LABEL.
6
+ class ConstantScope
7
+ # Returns predictions for the expressions described in the brief.
8
+ # @return [Hash<Symbol, Object>]
9
+ def self.predictions = { lexical_label: 'outer', shared_class_count: 0, new_block_local_visible: true }
10
+
11
+ # Creates a new counter closure with independent local state.
12
+ # @return [Proc]
13
+ def self.counter
14
+ @count = 0
15
+ -> { @count += 1 }
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,5 @@
1
+ # Hint
2
+
3
+ Constant lookup follows lexical nesting; inherited class variables can be shared.
4
+
5
+ An instance variable on the Exercises::ConstantScope class is shared by all closures using that module as self.
@@ -0,0 +1,8 @@
1
+ # A useful custom collection
2
+
3
+ Packet wraps numbers. Implement each to yield all values and return an Enumerator without a block; include Enumerable. Order Packet objects by the sum of their values through Comparable and <=>. to_s should return "Packet(total)". `protocol` returns whether a Packet responds to each and is an Object. Do not change the caller’s array.
4
+
5
+ Use `rkoans check` to investigate one failing check at a time. Hints are optional.
6
+
7
+ Edit `core_protocols.rb` in this exercise's folder. Checks call
8
+ `Exercises::CoreProtocols` and its example classes.
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ # The example deliberately contrasts received arguments with values actually used.
4
+ # rubocop:disable Lint/UnusedMethodArgument
5
+
6
+ module Exercises
7
+ # Packet wraps numbers.
8
+ class CoreProtocols
9
+ # Example Packet for core protocols.
10
+ class Packet
11
+ include Enumerable
12
+ include Comparable
13
+
14
+ # Stores the initial values used by this example.
15
+ # @return [void]
16
+ def initialize(values) = @values = values.dup
17
+
18
+ # Yields all stored numbers, or returns an Enumerator when no block is given.
19
+ # @return [Enumerator, Object]
20
+ def each
21
+ return enum_for(:each) unless block_given?
22
+
23
+ yield @values.first unless @values.empty?
24
+ end
25
+
26
+ # Returns the sum of the packet's stored numbers.
27
+ # @return [Integer]
28
+ def total = @values.sum
29
+ # Compares packet totals in ascending order.
30
+ # @return [Integer]
31
+ def <=>(other) = other.total <=> total
32
+ # Returns the packet's total in its printable representation.
33
+ # @return [String]
34
+ def to_s = 'Packet'
35
+ end
36
+
37
+ # Reports each support and ordinary object membership.
38
+ # @return [Array<Boolean>]
39
+ def self.protocol(packet) = [false, false]
40
+ end
41
+ end
42
+
43
+ # rubocop:enable Lint/UnusedMethodArgument
@@ -0,0 +1,5 @@
1
+ # Hint
2
+
3
+ Enumerable needs an each implementation; Comparable needs <=>.
4
+
5
+ A no-block each can return enum_for(:each), which uses Kernel’s enumeration support.
@@ -0,0 +1,8 @@
1
+ # Send it to the right receiver
2
+
3
+ Mailbox wraps a supplied array. Use Forwardable so push and size delegate to that supplied array, including later changes made directly to it. Do not copy it or delegate to the archive. Return Array#push’s normal result.
4
+
5
+ Use `rkoans check` to investigate one failing check at a time. Hints are optional.
6
+
7
+ Edit `delegation.rb` in this exercise's folder. Checks call
8
+ `Exercises::Delegation` and its example classes.
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'forwardable'
4
+ module Exercises
5
+ # Mailbox wraps a supplied array.
6
+ class Delegation
7
+ # Example Mailbox for delegation.
8
+ class Mailbox
9
+ extend Forwardable
10
+
11
+ # Stores the initial values used by this example.
12
+ # @return [void]
13
+ def initialize(items)
14
+ @items = items
15
+ @archive = []
16
+ end
17
+ def_delegators :@archive, :push, :size
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,5 @@
1
+ # Hint
2
+
3
+ A delegated method forwards to a particular receiver; the choice of receiver is part of the API.
4
+
5
+ Forwardable generates focused forwarding methods without writing every wrapper.
@@ -0,0 +1,8 @@
1
+ # Build readers without losing names
2
+
3
+ Implement `readers(names)` to return a new class with one instance reader per name, using define_method and instance_variable_get. Each method must retain its own name. Implement `evaluate(factor)` to evaluate "factor * 2" in its local binding. `instance_value(object,name)` should return that object’s @name through reflection. `class_value` should evaluate a class-level expression in the generated class context.
4
+
5
+ Use `rkoans check` to investigate one failing check at a time. Hints are optional.
6
+
7
+ Edit `dynamic_methods.rb` in this exercise's folder. Checks call
8
+ `Exercises::DynamicMethods` and its example classes.