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,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Exercises
4
+ # Keep independent counts for Parent and Child.
5
+ class ClassState
6
+ # Example Parent for class state.
7
+ class Parent
8
+ # Resets state belonging to this class object.
9
+ # @return [Integer]
10
+ def self.reset = @count = 0
11
+ # Returns this class object's counter, defaulting to zero.
12
+ # @return [Integer]
13
+ def self.count = @count || 0
14
+ # Increments this class object's counter.
15
+ # @return [Integer]
16
+ def self.increment = @count = count + 1
17
+ # Returns the label supplied by this class's inheritance chain.
18
+ # @return [String]
19
+ def self.label = 'parent'
20
+ end
21
+
22
+ # Example Child for class state.
23
+ class Child < Parent
24
+ # Returns the label supplied by this class's inheritance chain.
25
+ # @return [String]
26
+ def self.label = "#{super}-child"
27
+ end
28
+
29
+ # Returns the singleton class owning the label class method.
30
+ # @return [Class]
31
+ def self.singleton_owner = Parent.method(:label).owner
32
+ end
33
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Exercises
4
+ # Implement multipliers(numbers) returning one lambda per number.
5
+ class ClosureCapture
6
+ # Creates an independently captured lambda for each factor.
7
+ # @return [Array<Proc>]
8
+ def self.multipliers(numbers)
9
+ numbers.map { |factor| ->(value) { value * factor } }
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Exercises
4
+ # A reference implementation for comparison after completing the exercise.
5
+ class CollectionBasics
6
+ def self.koans
7
+ { mapped: [2, 4, 6], selected: [1, 3] }
8
+ end
9
+
10
+ def self.double_odds(numbers)
11
+ numbers.select(&:odd?).map { |number| number * 2 }
12
+ end
13
+ end
14
+ end
@@ -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: 'item', shared_class_count: 1, new_block_local_visible: false }
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,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ # These examples demonstrate yield rather than explicit block forwarding.
4
+ # rubocop:disable Style/ExplicitBlockArgument
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
+ @values.each { |value| yield value }
24
+ self
25
+ end
26
+
27
+ # Returns the sum of the packet's stored numbers.
28
+ # @return [Integer]
29
+ def total = @values.sum
30
+ # Compares packet totals in ascending order.
31
+ # @return [Integer]
32
+ def <=>(other) = total <=> other.total
33
+ # Returns the packet's total in its printable representation.
34
+ # @return [String]
35
+ def to_s = "Packet(#{total})"
36
+ end
37
+
38
+ # Reports each support and ordinary object membership.
39
+ # @return [Array<Boolean>]
40
+ def self.protocol(packet) = [packet.respond_to?(:each), packet.is_a?(Object)]
41
+ end
42
+ end
43
+
44
+ # rubocop:enable Style/ExplicitBlockArgument
@@ -0,0 +1,17 @@
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) = @items = items
14
+ def_delegators :@items, :push, :size
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ # The fixed literal expression is an isolated binding or syntax experiment.
4
+ # rubocop:disable Style/EvalWithLocation
5
+
6
+ module Exercises
7
+ # Implement readers(names) to return a new class with one instance reader per name, using
8
+ # define_method and instance_variable_get.
9
+ class DynamicMethods
10
+ # Builds a class whose readers capture their own instance-variable names.
11
+ # @return [Class]
12
+ def self.readers(names)
13
+ Class.new do
14
+ names.each do |name|
15
+ define_method(name) { instance_variable_get("@#{name}") }
16
+ end
17
+ end
18
+ end
19
+
20
+ # Evaluates a fixed literal expression with access to the local binding.
21
+ # @return [Integer]
22
+ def self.evaluate(factor) = eval('factor * 2', binding)
23
+ # Reads the named instance variable from the supplied object.
24
+ # @return [Object]
25
+ def self.instance_value(object, name) = object.instance_variable_get("@#{name}")
26
+ # Returns the class object seen as self inside class_eval.
27
+ # @return [Class]
28
+ def self.class_value(klass) = klass.class_eval { self }
29
+ end
30
+ end
31
+
32
+ # rubocop:enable Style/EvalWithLocation
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ # The example deliberately rescues and reraises to observe preserved exception state.
4
+ # rubocop:disable Lint/UselessRescue
5
+
6
+ module Exercises
7
+ # Implement trace(fail:): append "work"; if fail, raise and rescue a StandardError and append
8
+ # "rescue"; otherwise append "else".
9
+ class ExceptionFlow
10
+ # Implements trace.
11
+ def self.trace(fail:)
12
+ trail = ['work']
13
+ begin
14
+ raise StandardError, 'failure' if fail
15
+ rescue StandardError
16
+ trail << 'rescue'
17
+ else
18
+ trail << 'else'
19
+ ensure
20
+ trail << 'ensure'
21
+ end
22
+ trail
23
+ end
24
+
25
+ # Implements reraises.
26
+ def self.reraises
27
+ raise ArgumentError, 'original'
28
+ rescue ArgumentError
29
+ raise
30
+ end
31
+ end
32
+ end
33
+
34
+ # rubocop:enable Lint/UselessRescue
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Exercises
4
+ # A reference implementation for comparison after completing the exercise.
5
+ class HeredocLayout
6
+ # Strips common source indentation and interpolates the supplied name.
7
+ # @param name [String]
8
+ # @return [String]
9
+ def self.render(name)
10
+ <<~TEXT
11
+ Hello #{name}
12
+ Ruby
13
+ TEXT
14
+ end
15
+
16
+ # Returns literal interpolation syntax followed by a newline.
17
+ # @return [String]
18
+ def self.literal
19
+ <<~'TEXT'
20
+ Hello #{name}
21
+ TEXT
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ # The block name is observable through parameter metadata or the explicit forwarding example.
4
+ # The exercise makes positional, keyword, and block forwarding visible.
5
+ # rubocop:disable Naming/BlockForwarding, Style/ArgumentsForwarding
6
+
7
+ module Exercises
8
+ # Fix forward to preserve positional arguments, keyword arguments, and the block when calling
9
+ # target.
10
+ class KeywordForwarding
11
+ # Renders one positional payload with an optional block and suffix.
12
+ # @return [String]
13
+ def self.target(payload, suffix: '?')
14
+ rendered = block_given? ? yield(payload) : payload.to_s
15
+ rendered + suffix
16
+ end
17
+
18
+ # Forwards positional arguments, keywords, and the block to target.
19
+ # @return [String]
20
+ def self.forward(*args, **keywords, &block)
21
+ target(*args, **keywords, &block)
22
+ end
23
+ end
24
+ end
25
+
26
+ # rubocop:enable Naming/BlockForwarding, Style/ArgumentsForwarding
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Exercises
4
+ # Implement first_multiples(limit) to return the first limit positive multiples of seven, starting
5
+ # at seven, using the endless range (1..).
6
+ class LazyEnumeration
7
+ # Takes the requested number of multiples from a lazy infinite sequence.
8
+ # @return [Array<Integer>]
9
+ def self.first_multiples(limit) = (1..).lazy.select { |n| (n % 7).zero? }.first(limit)
10
+ end
11
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Exercises
4
+ # Fill predictions for these expressions: !!0, 5 / 2, 5 / 2.0, 1 + 2 * 3, !nil, %w[ruby rails], and (1..3).to_a.
5
+ class LiteralsAndOperators
6
+ # Implements predictions.
7
+ def self.predictions
8
+ {
9
+ zero_truthy: true,
10
+ integer_division: 2,
11
+ float_division: 2.5,
12
+ precedence: 7,
13
+ not_nil: true,
14
+ words: %w[ruby rails],
15
+ range: [1, 2, 3]
16
+ }
17
+ end
18
+
19
+ # Implements default for nil.
20
+ def self.default_for_nil(value) = value.nil? ? 'missing' : value
21
+ end
22
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Exercises
4
+ # Fix format_order(name, quantity=1, *extras, unit:, **options, &block) to return
5
+ # "name:quantity:unit:extra_count:priority" where priority defaults to "normal".
6
+ class MethodContracts
7
+ # Formats positional, rest, and keyword options, then applies an optional block.
8
+ # @return [String]
9
+ def self.format_order(name, quantity = 1, *extras, unit:, **options, &block)
10
+ text = "#{name}:#{quantity}:#{unit}:#{extras.size}:#{options.fetch(:priority, 'normal')}"
11
+ block ? block.call(text) : text
12
+ end
13
+
14
+ # Reports the parameter kinds and names of format_order.
15
+ # @return [Array<Array<Symbol>>]
16
+ def self.parameters = method(:format_order).parameters
17
+ end
18
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Exercises
4
+ # Presenter#call returns "base".
5
+ class MethodLookup
6
+ # Example Wrapper for method lookup.
7
+ module Wrapper
8
+ # Returns the value from this scope's example receiver.
9
+ # @return [String]
10
+ def call = "[#{super}]"
11
+ end
12
+
13
+ # Example Presenter for method lookup.
14
+ class Presenter
15
+ prepend Wrapper
16
+
17
+ # Returns the value from this scope's example receiver.
18
+ # @return [String]
19
+ def call = 'base'
20
+ end
21
+
22
+ # Lists the first two ancestor names in method lookup order.
23
+ # @return [Array<String>]
24
+ def self.lookup = Presenter.ancestors.first(2).map(&:name)
25
+ end
26
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Explicit return is the subject of this example.
4
+ # rubocop:disable Style/RedundantReturn
5
+
6
+ module Exercises
7
+ # Implement lambda_trace so return inside the lambda ends only that lambda, and the method still
8
+ # appends "after".
9
+ class NonlocalExit
10
+ # Collects the lambda result and continues the surrounding method.
11
+ # @return [Array<String>]
12
+ def self.lambda_trace
13
+ action = -> { return 'inside' }
14
+ [action.call, 'after']
15
+ end
16
+
17
+ # Returns a proc whose later return targets this already completed method.
18
+ # @return [Proc]
19
+ def self.escaped_proc = proc { return :gone }
20
+
21
+ # Uses catch and throw to find the first even number across nested groups.
22
+ # @return [Integer, nil]
23
+ def self.find_even(groups)
24
+ catch(:found) do
25
+ groups.each do |group|
26
+ group.each { |value| throw :found, value if value.even? }
27
+ end
28
+ nil
29
+ end
30
+ end
31
+
32
+ # Skips odd values while collecting the even numbers.
33
+ # @return [Array<Integer>]
34
+ def self.skip_odds(values)
35
+ collected = []
36
+ values.each do |value|
37
+ next if value.odd?
38
+
39
+ collected << value
40
+ end
41
+ collected
42
+ end
43
+ end
44
+ end
45
+
46
+ # rubocop:enable Style/RedundantReturn
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Two numbered parameters deliberately demonstrate pair destructuring.
4
+ # rubocop:disable Style/NumberedParametersLimit
5
+
6
+ module Exercises
7
+ # Implement pair_sums using the block’s input pairs; for [[2,3],[4,5]], return [5,9].
8
+ class NumberedParameters
9
+ # Adds both components of each pair using numbered parameters.
10
+ # @return [Array<Integer>]
11
+ def self.pair_sums(pairs) = pairs.map { _1 + _2 }
12
+ # Returns predictions for the expressions described in the brief.
13
+ # @return [Hash<Symbol, Object>]
14
+ def self.predictions = { explicit_and_numbered: false, numbered_pair: true }
15
+ end
16
+ end
17
+
18
+ # rubocop:enable Style/NumberedParametersLimit
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ # The original descriptive check identifiers and example strings remain intact.
4
+ # Short parameter names match the small arithmetic or assignment examples.
5
+ # rubocop:disable Layout/LineLength, Naming/MethodParameterName
6
+
7
+ module Exercises
8
+ # Implement ratios(a,b) returning integer division, floating division, and exact Rational division under keys integer, floating, rational.
9
+ class NumericPrecision
10
+ # Implements ratios.
11
+ def self.ratios(a, b) = { integer: a / b, floating: a.fdiv(b), rational: Rational(a, b) }
12
+ # Implements imaginary product.
13
+ def self.imaginary_product(a, b) = Complex(0, a) * Complex(0, b)
14
+ end
15
+ end
16
+
17
+ # rubocop:enable Layout/LineLength, Naming/MethodParameterName
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Exercises
4
+ # Implement amount(payload, kind) to return a positive Integer amount only when a hash has type
5
+ # equal to the supplied kind and amount is an Integer greater than zero.
6
+ class PatternMatching
7
+ # Implements amount.
8
+ def self.amount(payload, kind)
9
+ case payload
10
+ in { type: ^kind, amount: Integer => number } if number.positive?
11
+ number
12
+ else
13
+ nil
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Exercises
4
+ # Speaker#say normally returns "plain".
5
+ class RefinementScope
6
+ # Example Speaker for refinement scope.
7
+ class Speaker
8
+ # Returns the voice selected by the lexical refinement scope.
9
+ # @return [String]
10
+ def say = 'plain'
11
+ end
12
+
13
+ # Example Voice for refinement scope.
14
+ module Voice
15
+ refine Speaker do
16
+ # Returns the voice selected by the lexical refinement scope.
17
+ # @return [String]
18
+ def say = 'local'
19
+ end
20
+ end
21
+
22
+ # Example Local for refinement scope.
23
+ module Local
24
+ using Voice
25
+ # Returns the value from this scope's example receiver.
26
+ # @return [String]
27
+ def self.call = Speaker.new.say
28
+ end
29
+
30
+ # Returns the unrefined voice outside the local scope.
31
+ # @return [String]
32
+ def self.outside = Speaker.new.say
33
+ end
34
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ # The example explicitly observes the regexp capture variable.
4
+ # rubocop:disable Style/SpecialGlobalVars
5
+
6
+ module Exercises
7
+ # Implement parse(text) for an entire string of lowercase name, colon, and decimal digits.
8
+ class RegexpCaptures
9
+ # Implements parse.
10
+ def self.parse(text)
11
+ match = /\A(?<name>[a-z]+):(?<id>\d+)\z/.match(text)
12
+ match && { name: match[:name], id: match[:id].to_i }
13
+ end
14
+
15
+ # Implements probe.
16
+ def self.probe(text)
17
+ /old/.match('old')
18
+ matched = /ruby/.match?(text)
19
+ [$~&.to_s, matched]
20
+ end
21
+ end
22
+ end
23
+
24
+ # rubocop:enable Style/SpecialGlobalVars
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Exercises
4
+ # A reference implementation for comparison after completing the exercise.
5
+ class RuntimeContext
6
+ # Returns process inputs and runtime metadata with an independent argument array.
7
+ # The greeting is nil when RKOANS_GREETING is absent; file fields are basenames.
8
+ def self.context
9
+ {
10
+ arguments: ARGV.dup,
11
+ greeting: ENV.fetch('RKOANS_GREETING', nil),
12
+ program: File.basename($PROGRAM_NAME),
13
+ file: File.basename(__FILE__),
14
+ encoding: __ENCODING__.name,
15
+ ruby: RUBY_VERSION
16
+ }
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Exercises
4
+ # Builds rows whose mutable contents are independent.
5
+ class SharedRows
6
+ # Returns count empty rows, each with its own mutable array.
7
+ # @param count [Integer] nonnegative number of rows
8
+ # @return [Array<Array<Object>>]
9
+ def self.rows(count)
10
+ Array.new(count) { [] }
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'singleton'
4
+ module Exercises
5
+ # Use the standard-library Singleton module so Configuration.instance returns the same instance
6
+ # and Configuration.new is not a public constructor.
7
+ class SingletonPattern
8
+ # Example Configuration for singleton pattern.
9
+ class Configuration
10
+ include Singleton
11
+
12
+ attr_accessor :mode
13
+
14
+ # Stores the initial values used by this example.
15
+ # @return [void]
16
+ def initialize = @mode = 'learning'
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'time'
4
+ require 'date'
5
+ module Exercises
6
+ # Implement utc(text) to parse an ISO8601 timestamp with an explicit offset and return the same
7
+ # instant formatted in UTC.
8
+ class TimeAndDate
9
+ # Normalizes an offset ISO8601 timestamp to its UTC representation.
10
+ # @return [String]
11
+ def self.utc(text) = Time.iso8601(text).utc.iso8601
12
+ # Returns the signed integer calendar-day difference between ISO dates.
13
+ # @return [Integer]
14
+ def self.days_between(first, last) = (Date.iso8601(last) - Date.iso8601(first)).to_i
15
+ end
16
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ # The explicit receiver is part of the method-call experiment.
4
+ # Explicit getter definitions are compared with attr_reader and attr_accessor.
5
+ # rubocop:disable Style/RedundantSelf, Style/TrivialAccessors
6
+
7
+ module Exercises
8
+ # Wallet has an internal balance reader used when comparing wallets, and a normalizer used within
9
+ # deposit.
10
+ class Visibility
11
+ # Example Wallet for visibility.
12
+ class Wallet
13
+ # Stores the initial values used by this example.
14
+ # @return [void]
15
+ def initialize(balance) = @balance = balance
16
+ # Returns the protected balance used for peer comparisons.
17
+ # @return [Integer]
18
+ def balance = @balance
19
+ # Converts a deposit amount to its nonnegative value.
20
+ # @return [Integer]
21
+ def normalize(value) = value.abs
22
+ # Adds the normalized amount to the balance.
23
+ # @return [Integer]
24
+ def deposit(value) = @balance += self.normalize(value)
25
+ # Compares this balance with another wallet's balance.
26
+ # @return [Integer]
27
+ def compare(other) = balance <=> other.balance
28
+ protected :balance
29
+ private :normalize
30
+ end
31
+ end
32
+ end
33
+
34
+ # rubocop:enable Style/RedundantSelf, Style/TrivialAccessors