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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +13 -0
- data/CURRICULUM.md +86 -0
- data/README.md +77 -0
- data/THIRD_PARTY_NOTICES.md +30 -0
- data/exercises/about-array-assignment/about_array_assignment.rb +45 -0
- data/exercises/about-array-assignment/brief.md +11 -0
- data/exercises/about-array-assignment/hint.md +11 -0
- data/exercises/about-arrays/about_arrays.rb +77 -0
- data/exercises/about-arrays/brief.md +16 -0
- data/exercises/about-arrays/hint.md +13 -0
- data/exercises/about-asserts/about_asserts.rb +22 -0
- data/exercises/about-asserts/brief.md +22 -0
- data/exercises/about-asserts/hint.md +10 -0
- data/exercises/about-blocks/about_blocks.rb +76 -0
- data/exercises/about-blocks/brief.md +44 -0
- data/exercises/about-blocks/hint.md +7 -0
- data/exercises/about-class-methods/about_class_methods.rb +105 -0
- data/exercises/about-class-methods/brief.md +73 -0
- data/exercises/about-class-methods/hint.md +8 -0
- data/exercises/about-classes/about_classes.rb +131 -0
- data/exercises/about-classes/brief.md +73 -0
- data/exercises/about-classes/hint.md +7 -0
- data/exercises/about-constants/about_constants.rb +49 -0
- data/exercises/about-constants/brief.md +51 -0
- data/exercises/about-constants/hint.md +7 -0
- data/exercises/about-control-statements/about_control_statements.rb +152 -0
- data/exercises/about-control-statements/brief.md +9 -0
- data/exercises/about-control-statements/hint.md +7 -0
- data/exercises/about-dice-project/about_dice_project.rb +27 -0
- data/exercises/about-dice-project/brief.md +12 -0
- data/exercises/about-dice-project/hint.md +5 -0
- data/exercises/about-exceptions/about_exceptions.rb +84 -0
- data/exercises/about-exceptions/brief.md +19 -0
- data/exercises/about-exceptions/hint.md +8 -0
- data/exercises/about-extra-credit/about_extra_credit.rb +117 -0
- data/exercises/about-extra-credit/brief.md +28 -0
- data/exercises/about-extra-credit/hint.md +5 -0
- data/exercises/about-hashes/about_hashes.rb +160 -0
- data/exercises/about-hashes/brief.md +9 -0
- data/exercises/about-hashes/hint.md +8 -0
- data/exercises/about-inheritance/about_inheritance.rb +63 -0
- data/exercises/about-inheritance/brief.md +50 -0
- data/exercises/about-inheritance/hint.md +8 -0
- data/exercises/about-iteration/about_iteration.rb +96 -0
- data/exercises/about-iteration/brief.md +26 -0
- data/exercises/about-iteration/hint.md +6 -0
- data/exercises/about-keyword-arguments/about_keyword_arguments.rb +56 -0
- data/exercises/about-keyword-arguments/brief.md +28 -0
- data/exercises/about-keyword-arguments/hint.md +7 -0
- data/exercises/about-message-passing/about_message_passing.rb +112 -0
- data/exercises/about-message-passing/brief.md +59 -0
- data/exercises/about-message-passing/hint.md +8 -0
- data/exercises/about-methods/about_methods.rb +104 -0
- data/exercises/about-methods/brief.md +55 -0
- data/exercises/about-methods/hint.md +8 -0
- data/exercises/about-modules/about_modules.rb +43 -0
- data/exercises/about-modules/brief.md +44 -0
- data/exercises/about-modules/hint.md +8 -0
- data/exercises/about-nil/about_nil.rb +29 -0
- data/exercises/about-nil/brief.md +12 -0
- data/exercises/about-nil/hint.md +11 -0
- data/exercises/about-objects/about_objects.rb +51 -0
- data/exercises/about-objects/brief.md +14 -0
- data/exercises/about-objects/hint.md +12 -0
- data/exercises/about-open-classes/about_open_classes.rb +38 -0
- data/exercises/about-open-classes/brief.md +34 -0
- data/exercises/about-open-classes/hint.md +7 -0
- data/exercises/about-pattern-matching/about_pattern_matching.rb +106 -0
- data/exercises/about-pattern-matching/brief.md +124 -0
- data/exercises/about-pattern-matching/hint.md +8 -0
- data/exercises/about-proxy-object-project/about_proxy_object_project.rb +43 -0
- data/exercises/about-proxy-object-project/brief.md +10 -0
- data/exercises/about-proxy-object-project/hint.md +5 -0
- data/exercises/about-regular-expressions/about_regular_expressions.rb +174 -0
- data/exercises/about-regular-expressions/brief.md +9 -0
- data/exercises/about-regular-expressions/hint.md +8 -0
- data/exercises/about-sandwich-code/about_sandwich_code.rb +58 -0
- data/exercises/about-sandwich-code/brief.md +14 -0
- data/exercises/about-sandwich-code/hint.md +5 -0
- data/exercises/about-scope/about_scope.rb +76 -0
- data/exercises/about-scope/brief.md +35 -0
- data/exercises/about-scope/hint.md +8 -0
- data/exercises/about-scoring-project/about_scoring_project.rb +16 -0
- data/exercises/about-scoring-project/brief.md +10 -0
- data/exercises/about-scoring-project/hint.md +5 -0
- data/exercises/about-strings/about_strings.rb +142 -0
- data/exercises/about-strings/brief.md +22 -0
- data/exercises/about-strings/hint.md +11 -0
- data/exercises/about-symbols/about_symbols.rb +53 -0
- data/exercises/about-symbols/brief.md +21 -0
- data/exercises/about-symbols/hint.md +12 -0
- data/exercises/about-to-str/about_to_str.rb +49 -0
- data/exercises/about-to-str/brief.md +37 -0
- data/exercises/about-to-str/hint.md +7 -0
- data/exercises/about-triangle-project/about_triangle_project.rb +15 -0
- data/exercises/about-triangle-project/brief.md +11 -0
- data/exercises/about-triangle-project/hint.md +5 -0
- data/exercises/about-triangle-project-two/about_triangle_project_two.rb +22 -0
- data/exercises/about-triangle-project-two/brief.md +10 -0
- data/exercises/about-triangle-project-two/hint.md +5 -0
- data/exercises/about-true-and-false/about_true_and_false.rb +26 -0
- data/exercises/about-true-and-false/brief.md +22 -0
- data/exercises/about-true-and-false/hint.md +7 -0
- data/exercises/blocks-and-methods/blocks_and_methods.rb +14 -0
- data/exercises/blocks-and-methods/brief.md +8 -0
- data/exercises/blocks-and-methods/hint.md +6 -0
- data/exercises/catalog.json +61 -0
- data/exercises/class-state/brief.md +8 -0
- data/exercises/class-state/class_state.rb +39 -0
- data/exercises/class-state/hint.md +5 -0
- data/exercises/closure-capture/brief.md +8 -0
- data/exercises/closure-capture/closure_capture.rb +21 -0
- data/exercises/closure-capture/hint.md +5 -0
- data/exercises/collection-basics/brief.md +8 -0
- data/exercises/collection-basics/collection_basics.rb +16 -0
- data/exercises/collection-basics/hint.md +6 -0
- data/exercises/constant-scope/brief.md +8 -0
- data/exercises/constant-scope/constant_scope.rb +18 -0
- data/exercises/constant-scope/hint.md +5 -0
- data/exercises/core-protocols/brief.md +8 -0
- data/exercises/core-protocols/core_protocols.rb +43 -0
- data/exercises/core-protocols/hint.md +5 -0
- data/exercises/delegation/brief.md +8 -0
- data/exercises/delegation/delegation.rb +20 -0
- data/exercises/delegation/hint.md +5 -0
- data/exercises/dynamic-methods/brief.md +8 -0
- data/exercises/dynamic-methods/dynamic_methods.rb +33 -0
- data/exercises/dynamic-methods/hint.md +5 -0
- data/exercises/exception-flow/brief.md +8 -0
- data/exercises/exception-flow/exception_flow.rb +27 -0
- data/exercises/exception-flow/hint.md +5 -0
- data/exercises/heredoc-layout/brief.md +14 -0
- data/exercises/heredoc-layout/heredoc_layout.rb +25 -0
- data/exercises/heredoc-layout/hint.md +9 -0
- data/exercises/keyword-forwarding/brief.md +8 -0
- data/exercises/keyword-forwarding/hint.md +5 -0
- data/exercises/keyword-forwarding/keyword_forwarding.rb +27 -0
- data/exercises/lazy-enumeration/brief.md +8 -0
- data/exercises/lazy-enumeration/hint.md +5 -0
- data/exercises/lazy-enumeration/lazy_enumeration.rb +16 -0
- data/exercises/literals-and-operators/brief.md +20 -0
- data/exercises/literals-and-operators/hint.md +5 -0
- data/exercises/literals-and-operators/literals_and_operators.rb +15 -0
- data/exercises/method-contracts/brief.md +8 -0
- data/exercises/method-contracts/hint.md +5 -0
- data/exercises/method-contracts/method_contracts.rb +22 -0
- data/exercises/method-lookup/brief.md +8 -0
- data/exercises/method-lookup/hint.md +5 -0
- data/exercises/method-lookup/method_lookup.rb +26 -0
- data/exercises/nonlocal-exit/brief.md +8 -0
- data/exercises/nonlocal-exit/hint.md +5 -0
- data/exercises/nonlocal-exit/nonlocal_exit.rb +29 -0
- data/exercises/numbered-parameters/brief.md +18 -0
- data/exercises/numbered-parameters/hint.md +5 -0
- data/exercises/numbered-parameters/numbered_parameters.rb +18 -0
- data/exercises/numeric-precision/brief.md +8 -0
- data/exercises/numeric-precision/hint.md +5 -0
- data/exercises/numeric-precision/numeric_precision.rb +17 -0
- data/exercises/pattern-matching/brief.md +8 -0
- data/exercises/pattern-matching/hint.md +5 -0
- data/exercises/pattern-matching/pattern_matching.rb +22 -0
- data/exercises/refinement-scope/brief.md +8 -0
- data/exercises/refinement-scope/hint.md +5 -0
- data/exercises/refinement-scope/refinement_scope.rb +33 -0
- data/exercises/regexp-captures/brief.md +8 -0
- data/exercises/regexp-captures/hint.md +5 -0
- data/exercises/regexp-captures/regexp_captures.rb +25 -0
- data/exercises/runtime-context/brief.md +20 -0
- data/exercises/runtime-context/hint.md +8 -0
- data/exercises/runtime-context/runtime_context.rb +11 -0
- data/exercises/shared-rows/brief.md +8 -0
- data/exercises/shared-rows/hint.md +7 -0
- data/exercises/shared-rows/shared_rows.rb +13 -0
- data/exercises/singleton-pattern/brief.md +8 -0
- data/exercises/singleton-pattern/hint.md +5 -0
- data/exercises/singleton-pattern/singleton_pattern.rb +20 -0
- data/exercises/time-and-date/brief.md +8 -0
- data/exercises/time-and-date/hint.md +5 -0
- data/exercises/time-and-date/time_and_date.rb +21 -0
- data/exercises/visibility/brief.md +8 -0
- data/exercises/visibility/hint.md +5 -0
- data/exercises/visibility/visibility.rb +32 -0
- data/lib/rkoans/catalog.rb +31 -0
- data/lib/rkoans/checker.rb +62 -0
- data/lib/rkoans/cli.rb +79 -0
- data/lib/rkoans/error.rb +6 -0
- data/lib/rkoans/exercise.rb +50 -0
- data/lib/rkoans/keyboard.rb +51 -0
- data/lib/rkoans/progress.rb +39 -0
- data/lib/rkoans/selection.rb +31 -0
- data/lib/rkoans/session.rb +127 -0
- data/lib/rkoans/terminal_view.rb +99 -0
- data/lib/rkoans/version.rb +1 -1
- data/lib/rkoans/watcher.rb +58 -0
- data/lib/rkoans.rb +13 -3
- data/sig/about_array_assignment_acceptance_test.rbs +3 -0
- data/sig/about_arrays_acceptance_test.rbs +3 -0
- data/sig/about_asserts_command_test.rbs +4 -0
- data/sig/about_blocks_acceptance_test.rbs +3 -0
- data/sig/about_class_methods_acceptance_test.rbs +3 -0
- data/sig/about_classes_acceptance_test.rbs +3 -0
- data/sig/about_constants_acceptance_test.rbs +3 -0
- data/sig/about_control_statements_acceptance_test.rbs +3 -0
- data/sig/about_dice_project_acceptance_test.rbs +3 -0
- data/sig/about_exceptions_acceptance_test.rbs +3 -0
- data/sig/about_extra_credit_acceptance_test.rbs +5 -0
- data/sig/about_hashes_acceptance_test.rbs +3 -0
- data/sig/about_inheritance_acceptance_test.rbs +3 -0
- data/sig/about_iteration_acceptance_test.rbs +3 -0
- data/sig/about_keyword_arguments_acceptance_test.rbs +3 -0
- data/sig/about_message_passing_acceptance_test.rbs +3 -0
- data/sig/about_methods_acceptance_test.rbs +3 -0
- data/sig/about_modules_acceptance_test.rbs +3 -0
- data/sig/about_nil_acceptance_test.rbs +3 -0
- data/sig/about_objects_acceptance_test.rbs +3 -0
- data/sig/about_open_classes_acceptance_test.rbs +3 -0
- data/sig/about_pattern_matching_acceptance_test.rbs +3 -0
- data/sig/about_proxy_object_project_acceptance_test.rbs +3 -0
- data/sig/about_regular_expressions_acceptance_test.rbs +3 -0
- data/sig/about_sandwich_code_acceptance_test.rbs +3 -0
- data/sig/about_scope_acceptance_test.rbs +3 -0
- data/sig/about_scoring_project_acceptance_test.rbs +3 -0
- data/sig/about_strings_acceptance_test.rbs +3 -0
- data/sig/about_symbols_acceptance_test.rbs +3 -0
- data/sig/about_to_str_acceptance_test.rbs +3 -0
- data/sig/about_triangle_project_acceptance_test.rbs +3 -0
- data/sig/about_triangle_project_two_acceptance_test.rbs +3 -0
- data/sig/about_true_and_false_command_test.rbs +4 -0
- data/sig/catalog_error_command_test.rbs +4 -0
- data/sig/checker_test.rbs +9 -0
- data/sig/class_state_acceptance_test.rbs +3 -0
- data/sig/closure_capture_acceptance_test.rbs +3 -0
- data/sig/command_support.rbs +18 -0
- data/sig/command_test.rbs +5 -0
- data/sig/constant_scope_acceptance_test.rbs +3 -0
- data/sig/core_protocols_acceptance_test.rbs +3 -0
- data/sig/curriculum_cop_test.rbs +9 -0
- data/sig/delegation_acceptance_test.rbs +3 -0
- data/sig/dynamic_methods_acceptance_test.rbs +3 -0
- data/sig/exception_flow_acceptance_test.rbs +3 -0
- data/sig/exercise_test.rbs +3 -0
- data/sig/exercises/about_array_assignment.rbs +36 -0
- data/sig/exercises/about_arrays.rbs +51 -0
- data/sig/exercises/about_asserts.rbs +23 -0
- data/sig/exercises/about_blocks.rbs +40 -0
- data/sig/exercises/about_class_methods.rbs +62 -0
- data/sig/exercises/about_classes.rbs +88 -0
- data/sig/exercises/about_constants.rbs +53 -0
- data/sig/exercises/about_control_statements.rbs +46 -0
- data/sig/exercises/about_dice_project.rbs +16 -0
- data/sig/exercises/about_exceptions.rbs +36 -0
- data/sig/exercises/about_extra_credit.rbs +36 -0
- data/sig/exercises/about_hashes.rbs +62 -0
- data/sig/exercises/about_inheritance.rbs +50 -0
- data/sig/exercises/about_iteration.rbs +37 -0
- data/sig/exercises/about_keyword_arguments.rbs +33 -0
- data/sig/exercises/about_message_passing.rbs +68 -0
- data/sig/exercises/about_methods.rbs +68 -0
- data/sig/exercises/about_modules.rbs +38 -0
- data/sig/exercises/about_nil.rbs +23 -0
- data/sig/exercises/about_objects.rbs +38 -0
- data/sig/exercises/about_open_classes.rbs +31 -0
- data/sig/exercises/about_pattern_matching.rbs +65 -0
- data/sig/exercises/about_proxy_object_project.rbs +31 -0
- data/sig/exercises/about_regular_expressions.rbs +83 -0
- data/sig/exercises/about_sandwich_code.rbs +17 -0
- data/sig/exercises/about_scope.rbs +59 -0
- data/sig/exercises/about_scoring_project.rbs +16 -0
- data/sig/exercises/about_strings.rbs +85 -0
- data/sig/exercises/about_symbols.rbs +46 -0
- data/sig/exercises/about_to_str.rbs +36 -0
- data/sig/exercises/about_triangle_project.rbs +11 -0
- data/sig/exercises/about_triangle_project_two.rbs +12 -0
- data/sig/exercises/about_true_and_false.rbs +27 -0
- data/sig/exercises/blocks_and_methods.rbs +11 -0
- data/sig/exercises/class_state.rbs +19 -0
- data/sig/exercises/closure_capture.rbs +10 -0
- data/sig/exercises/collection_basics.rbs +6 -0
- data/sig/exercises/collection_basics_test.rbs +4 -0
- data/sig/exercises/constant_scope.rbs +11 -0
- data/sig/exercises/core_protocols.rbs +20 -0
- data/sig/exercises/delegation.rbs +14 -0
- data/sig/exercises/dynamic_methods.rbs +13 -0
- data/sig/exercises/exception_flow.rbs +11 -0
- data/sig/exercises/heredoc_layout.rbs +11 -0
- data/sig/exercises/keyword_forwarding.rbs +12 -0
- data/sig/exercises/lazy_enumeration.rbs +10 -0
- data/sig/exercises/literals_and_operators.rbs +12 -0
- data/sig/exercises/method_contracts.rbs +11 -0
- data/sig/exercises/method_lookup.rbs +16 -0
- data/sig/exercises/nonlocal_exit.rbs +14 -0
- data/sig/exercises/numbered_parameters.rbs +11 -0
- data/sig/exercises/numeric_precision.rbs +11 -0
- data/sig/exercises/pattern_matching.rbs +10 -0
- data/sig/exercises/refinement_scope.rbs +18 -0
- data/sig/exercises/regexp_captures.rbs +11 -0
- data/sig/exercises/runtime_context.rbs +23 -0
- data/sig/exercises/shared_rows.rbs +11 -0
- data/sig/exercises/singleton_pattern.rbs +14 -0
- data/sig/exercises/time_and_date.rbs +11 -0
- data/sig/exercises/visibility.rbs +18 -0
- data/sig/fixture_support.rbs +11 -0
- data/sig/help_hint_command_test.rbs +8 -0
- data/sig/heredoc_layout_acceptance_test.rbs +3 -0
- data/sig/keyboard_session_test.rbs +9 -0
- data/sig/keyword_forwarding_acceptance_test.rbs +3 -0
- data/sig/lazy_enumeration_acceptance_test.rbs +3 -0
- data/sig/literals_and_operators_acceptance_test.rbs +3 -0
- data/sig/method_contracts_acceptance_test.rbs +3 -0
- data/sig/method_lookup_acceptance_test.rbs +3 -0
- data/sig/nonlocal_exit_acceptance_test.rbs +3 -0
- data/sig/numbered_parameters_acceptance_test.rbs +3 -0
- data/sig/numeric_precision_acceptance_test.rbs +4 -0
- data/sig/packaging_test.rbs +3 -0
- data/sig/pattern_matching_acceptance_test.rbs +3 -0
- data/sig/reference_solutions_test.rbs +3 -0
- data/sig/refinement_scope_acceptance_test.rbs +3 -0
- data/sig/regexp_captures_acceptance_test.rbs +4 -0
- data/sig/rkoans/catalog.rbs +11 -0
- data/sig/rkoans/checker.rbs +22 -0
- data/sig/rkoans/cli.rbs +21 -0
- data/sig/rkoans/exercise.rbs +18 -0
- data/sig/rkoans/keyboard.rbs +13 -0
- data/sig/rkoans/progress.rbs +9 -0
- data/sig/rkoans/selection.rbs +9 -0
- data/sig/rkoans/session.rbs +30 -0
- data/sig/rkoans/terminal_view.rbs +24 -0
- data/sig/rkoans/watcher.rbs +18 -0
- data/sig/rkoans.rbs +2 -0
- data/sig/runtime_context_command_test.rbs +4 -0
- data/sig/selection_command_test.rbs +5 -0
- data/sig/session_command_test.rbs +12 -0
- data/sig/session_edge_cases_test.rbs +4 -0
- data/sig/shared_rows_acceptance_test.rbs +3 -0
- data/sig/singleton_pattern_acceptance_test.rbs +3 -0
- data/sig/time_and_date_acceptance_test.rbs +4 -0
- data/sig/visibility_acceptance_test.rbs +4 -0
- data/sig/watcher_test.rbs +3 -0
- data/solutions/about-array-assignment/about_array_assignment.rb +36 -0
- data/solutions/about-arrays/about_arrays.rb +53 -0
- data/solutions/about-asserts/about_asserts.rb +22 -0
- data/solutions/about-blocks/about_blocks.rb +30 -0
- data/solutions/about-class-methods/about_class_methods.rb +36 -0
- data/solutions/about-classes/about_classes.rb +40 -0
- data/solutions/about-constants/about_constants.rb +26 -0
- data/solutions/about-control-statements/about_control_statements.rb +35 -0
- data/solutions/about-dice-project/about_dice_project.rb +27 -0
- data/solutions/about-exceptions/about_exceptions.rb +30 -0
- data/solutions/about-extra-credit/about_extra_credit.rb +114 -0
- data/solutions/about-hashes/about_hashes.rb +52 -0
- data/solutions/about-inheritance/about_inheritance.rb +27 -0
- data/solutions/about-iteration/about_iteration.rb +31 -0
- data/solutions/about-keyword-arguments/about_keyword_arguments.rb +28 -0
- data/solutions/about-message-passing/about_message_passing.rb +38 -0
- data/solutions/about-methods/about_methods.rb +39 -0
- data/solutions/about-modules/about_modules.rb +23 -0
- data/solutions/about-nil/about_nil.rb +23 -0
- data/solutions/about-objects/about_objects.rb +34 -0
- data/solutions/about-open-classes/about_open_classes.rb +23 -0
- data/solutions/about-pattern-matching/about_pattern_matching.rb +39 -0
- data/solutions/about-proxy-object-project/about_proxy_object_project.rb +44 -0
- data/solutions/about-regular-expressions/about_regular_expressions.rb +60 -0
- data/solutions/about-sandwich-code/about_sandwich_code.rb +60 -0
- data/solutions/about-scope/about_scope.rb +33 -0
- data/solutions/about-scoring-project/about_scoring_project.rb +19 -0
- data/solutions/about-strings/about_strings.rb +56 -0
- data/solutions/about-symbols/about_symbols.rb +35 -0
- data/solutions/about-to-str/about_to_str.rb +24 -0
- data/solutions/about-triangle-project/about_triangle_project.rb +19 -0
- data/solutions/about-triangle-project-two/about_triangle_project_two.rb +25 -0
- data/solutions/about-true-and-false/about_true_and_false.rb +25 -0
- data/solutions/blocks-and-methods/blocks_and_methods.rb +14 -0
- data/solutions/class-state/class_state.rb +33 -0
- data/solutions/closure-capture/closure_capture.rb +12 -0
- data/solutions/collection-basics/collection_basics.rb +14 -0
- data/solutions/constant-scope/constant_scope.rb +18 -0
- data/solutions/core-protocols/core_protocols.rb +44 -0
- data/solutions/delegation/delegation.rb +17 -0
- data/solutions/dynamic-methods/dynamic_methods.rb +32 -0
- data/solutions/exception-flow/exception_flow.rb +34 -0
- data/solutions/heredoc-layout/heredoc_layout.rb +24 -0
- data/solutions/keyword-forwarding/keyword_forwarding.rb +26 -0
- data/solutions/lazy-enumeration/lazy_enumeration.rb +11 -0
- data/solutions/literals-and-operators/literals_and_operators.rb +22 -0
- data/solutions/method-contracts/method_contracts.rb +18 -0
- data/solutions/method-lookup/method_lookup.rb +26 -0
- data/solutions/nonlocal-exit/nonlocal_exit.rb +46 -0
- data/solutions/numbered-parameters/numbered_parameters.rb +18 -0
- data/solutions/numeric-precision/numeric_precision.rb +17 -0
- data/solutions/pattern-matching/pattern_matching.rb +17 -0
- data/solutions/refinement-scope/refinement_scope.rb +34 -0
- data/solutions/regexp-captures/regexp_captures.rb +24 -0
- data/solutions/runtime-context/runtime_context.rb +19 -0
- data/solutions/shared-rows/shared_rows.rb +13 -0
- data/solutions/singleton-pattern/singleton_pattern.rb +19 -0
- data/solutions/time-and-date/time_and_date.rb +16 -0
- data/solutions/visibility/visibility.rb +34 -0
- data/test/exercises/about_array_assignment_test.rb +87 -0
- data/test/exercises/about_arrays_test.rb +119 -0
- data/test/exercises/about_asserts_test.rb +41 -0
- data/test/exercises/about_blocks_test.rb +140 -0
- data/test/exercises/about_class_methods_test.rb +232 -0
- data/test/exercises/about_classes_test.rb +261 -0
- data/test/exercises/about_constants_test.rb +111 -0
- data/test/exercises/about_control_statements_test.rb +188 -0
- data/test/exercises/about_dice_project_test.rb +40 -0
- data/test/exercises/about_exceptions_test.rb +98 -0
- data/test/exercises/about_extra_credit_test.rb +74 -0
- data/test/exercises/about_hashes_test.rb +163 -0
- data/test/exercises/about_inheritance_test.rb +121 -0
- data/test/exercises/about_iteration_test.rb +148 -0
- data/test/exercises/about_keyword_arguments_test.rb +80 -0
- data/test/exercises/about_message_passing_test.rb +230 -0
- data/test/exercises/about_methods_test.rb +208 -0
- data/test/exercises/about_modules_test.rb +98 -0
- data/test/exercises/about_nil_test.rb +35 -0
- data/test/exercises/about_objects_test.rb +74 -0
- data/test/exercises/about_open_classes_test.rb +60 -0
- data/test/exercises/about_pattern_matching_test.rb +257 -0
- data/test/exercises/about_proxy_object_project_test.rb +75 -0
- data/test/exercises/about_regular_expressions_test.rb +243 -0
- data/test/exercises/about_sandwich_code_test.rb +82 -0
- data/test/exercises/about_scope_test.rb +123 -0
- data/test/exercises/about_scoring_project_test.rb +62 -0
- data/test/exercises/about_strings_test.rb +255 -0
- data/test/exercises/about_symbols_test.rb +120 -0
- data/test/exercises/about_to_str_test.rb +89 -0
- data/test/exercises/about_triangle_project_test.rb +29 -0
- data/test/exercises/about_triangle_project_two_test.rb +28 -0
- data/test/exercises/about_true_and_false_test.rb +43 -0
- data/test/exercises/blocks_and_methods_test.rb +22 -0
- data/test/exercises/class_state_test.rb +29 -0
- data/test/exercises/closure_capture_test.rb +29 -0
- data/test/exercises/collection_basics_test.rb +18 -0
- data/test/exercises/constant_scope_test.rb +18 -0
- data/test/exercises/core_protocols_test.rb +28 -0
- data/test/exercises/delegation_test.rb +23 -0
- data/test/exercises/dynamic_methods_test.rb +28 -0
- data/test/exercises/exception_flow_test.rb +17 -0
- data/test/exercises/heredoc_layout_test.rb +18 -0
- data/test/exercises/keyword_forwarding_test.rb +22 -0
- data/test/exercises/lazy_enumeration_test.rb +15 -0
- data/test/exercises/literals_and_operators_test.rb +25 -0
- data/test/exercises/method_contracts_test.rb +28 -0
- data/test/exercises/method_lookup_test.rb +14 -0
- data/test/exercises/nonlocal_exit_test.rb +22 -0
- data/test/exercises/numbered_parameters_test.rb +15 -0
- data/test/exercises/numeric_precision_test.rb +24 -0
- data/test/exercises/pattern_matching_test.rb +18 -0
- data/test/exercises/refinement_scope_test.rb +14 -0
- data/test/exercises/regexp_captures_test.rb +20 -0
- data/test/exercises/runtime_context_test.rb +59 -0
- data/test/exercises/shared_rows_test.rb +34 -0
- data/test/exercises/singleton_pattern_test.rb +16 -0
- data/test/exercises/time_and_date_test.rb +22 -0
- data/test/exercises/visibility_test.rb +22 -0
- metadata +471 -4
- data/Rakefile +0 -12
- 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
|