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,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# SPDX-License-Identifier: CC-BY-NC-SA-3.0
|
|
4
|
+
# Adapted from Ruby Koans by Jim Weirich and Joe O'Brien.
|
|
5
|
+
# See THIRD_PARTY_NOTICES.md for attribution and license terms.
|
|
6
|
+
|
|
7
|
+
module Exercises
|
|
8
|
+
# A set of dice with stable values until the next roll.
|
|
9
|
+
class AboutDiceProject
|
|
10
|
+
# Stores the latest roll from an injectable random source.
|
|
11
|
+
class DiceSet
|
|
12
|
+
attr_reader :values
|
|
13
|
+
|
|
14
|
+
# @param random [Random] source of uniform six-sided die values
|
|
15
|
+
def initialize(random: Random.new)
|
|
16
|
+
@random = random
|
|
17
|
+
@values = []
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# @param count [Integer] number of dice to roll
|
|
21
|
+
# @return [Array<Integer>] freshly rolled values
|
|
22
|
+
def roll(_count)
|
|
23
|
+
@values = []
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# Dice Project
|
|
2
|
+
|
|
3
|
+
Complete `Exercises::AboutDiceProject::DiceSet#roll(count)` in `about_dice_project.rb`.
|
|
4
|
+
Replace `values` with exactly `count` integers from 1 through 6. Values must stay
|
|
5
|
+
stable when read and only change when rolled. Zero dice produces an empty array.
|
|
6
|
+
Use the random source supplied to the constructor and call `rand(1..6)` once
|
|
7
|
+
per die. Normal use defaults to `Random.new`; checks supply a seeded source.
|
|
8
|
+
|
|
9
|
+
Two genuinely random rolls can be equal. The checks therefore replay a known
|
|
10
|
+
random stream instead of requiring successive rolls to differ.
|
|
11
|
+
|
|
12
|
+
Adapted from Ruby Koans by Jim Weirich and Joe O'Brien, licensed under CC BY-NC-SA 3.0. See `THIRD_PARTY_NOTICES.md`.
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# SPDX-License-Identifier: CC-BY-NC-SA-3.0
|
|
4
|
+
# Adapted from Ruby Koans by Jim Weirich and Joe O'Brien.
|
|
5
|
+
# See THIRD_PARTY_NOTICES.md for attribution and license terms.
|
|
6
|
+
|
|
7
|
+
module Exercises
|
|
8
|
+
# Predictions for exceptions examples.
|
|
9
|
+
class AboutExceptions
|
|
10
|
+
# Replace each :fill_me_in with the result of the described expression.
|
|
11
|
+
# @return [Hash<Symbol, Object>]
|
|
12
|
+
# This method is an answer table, not a sequence of operations.
|
|
13
|
+
def self.koans
|
|
14
|
+
{
|
|
15
|
+
# Exceptions inherit from exception.
|
|
16
|
+
# assert_equal __, MySpecialError.ancestors[1]
|
|
17
|
+
# assert_equal __, MySpecialError.ancestors[2]
|
|
18
|
+
# assert_equal __, MySpecialError.ancestors[3]
|
|
19
|
+
# assert_equal __, MySpecialError.ancestors[4]
|
|
20
|
+
# Predict: MySpecialError.ancestors[1]
|
|
21
|
+
exceptions_inherit_from_Exception_one: :fill_me_in,
|
|
22
|
+
# Predict: MySpecialError.ancestors[2]
|
|
23
|
+
exceptions_inherit_from_Exception_two: :fill_me_in,
|
|
24
|
+
# Predict: MySpecialError.ancestors[3]
|
|
25
|
+
exceptions_inherit_from_Exception_three: :fill_me_in,
|
|
26
|
+
# Predict: MySpecialError.ancestors[4]
|
|
27
|
+
exceptions_inherit_from_Exception_four: :fill_me_in,
|
|
28
|
+
# Rescue clause.
|
|
29
|
+
# result = nil
|
|
30
|
+
# begin
|
|
31
|
+
# fail "Oops"
|
|
32
|
+
# rescue StandardError => ex
|
|
33
|
+
# result = :exception_handled
|
|
34
|
+
# end
|
|
35
|
+
# assert_equal __, result
|
|
36
|
+
# assert_equal __, ex.is_a?(StandardError), "Should be a Standard Error"
|
|
37
|
+
# assert_equal __, ex.is_a?(RuntimeError), "Should be a Runtime Error"
|
|
38
|
+
# assert RuntimeError.ancestors.include?(StandardError),
|
|
39
|
+
# "RuntimeError is a subclass of StandardError"
|
|
40
|
+
# assert_equal __, ex.message
|
|
41
|
+
# Predict: result
|
|
42
|
+
rescue_clause_one: :fill_me_in,
|
|
43
|
+
# Predict: ex.is_a?(StandardError)
|
|
44
|
+
rescue_clause_two: :fill_me_in,
|
|
45
|
+
# Predict: ex.is_a?(RuntimeError)
|
|
46
|
+
rescue_clause_three: :fill_me_in,
|
|
47
|
+
# Predict: ex.message
|
|
48
|
+
rescue_clause_four: :fill_me_in,
|
|
49
|
+
# Raising a particular error.
|
|
50
|
+
# result = nil
|
|
51
|
+
# begin
|
|
52
|
+
# 'raise' and 'fail' are synonyms
|
|
53
|
+
# raise MySpecialError, "My Message"
|
|
54
|
+
# rescue MySpecialError => ex
|
|
55
|
+
# result = :exception_handled
|
|
56
|
+
# end
|
|
57
|
+
# assert_equal __, result
|
|
58
|
+
# assert_equal __, ex.message
|
|
59
|
+
# Predict: result
|
|
60
|
+
raising_a_particular_error_one: :fill_me_in,
|
|
61
|
+
# Predict: ex.message
|
|
62
|
+
raising_a_particular_error_two: :fill_me_in,
|
|
63
|
+
# Ensure clause.
|
|
64
|
+
# result = nil
|
|
65
|
+
# begin
|
|
66
|
+
# fail "Oops"
|
|
67
|
+
# rescue StandardError
|
|
68
|
+
# no code here
|
|
69
|
+
# ensure
|
|
70
|
+
# result = :always_run
|
|
71
|
+
# end
|
|
72
|
+
# assert_equal __, result
|
|
73
|
+
# Predict: result
|
|
74
|
+
ensure_clause_one: :fill_me_in,
|
|
75
|
+
# Asserting an error is raised.
|
|
76
|
+
# assert_raise(___) do
|
|
77
|
+
# raise MySpecialError.new("New instances can be raised directly.")
|
|
78
|
+
# end
|
|
79
|
+
# Predict: exception class from: raise MySpecialError.new("New instances can be raised directly.")
|
|
80
|
+
asserting_an_error_is_raised_one: :fill_me_in
|
|
81
|
+
}
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# About Exceptions
|
|
2
|
+
|
|
3
|
+
Replace each `:fill_me_in` in `about_exceptions.rb` with the predicted result.
|
|
4
|
+
Each field identifies its example. Run the checks after edits to investigate the
|
|
5
|
+
next prediction. Answers include the Ruby values and exception classes shown by
|
|
6
|
+
the examples. Read the setup comments before evaluating an expression.
|
|
7
|
+
|
|
8
|
+
## Example definitions
|
|
9
|
+
|
|
10
|
+
These definitions supply the objects and methods used by the prediction examples.
|
|
11
|
+
They run in the check class `AboutExceptionsTest`.
|
|
12
|
+
|
|
13
|
+
```ruby
|
|
14
|
+
class MySpecialError < RuntimeError
|
|
15
|
+
end
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Adapted from Ruby Koans by Jim Weirich and Joe O'Brien, licensed under
|
|
19
|
+
CC BY-NC-SA 3.0. See `THIRD_PARTY_NOTICES.md` for attribution and license terms.
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# Hint
|
|
2
|
+
|
|
3
|
+
Follow the raised exception through rescue and ensure. Inspect its class,
|
|
4
|
+
ancestors, and message. A rescue chooses compatible exception classes; ensure
|
|
5
|
+
runs even after an exception is handled.
|
|
6
|
+
|
|
7
|
+
Adapted from Ruby Koans by Jim Weirich and Joe O'Brien, licensed under
|
|
8
|
+
CC BY-NC-SA 3.0. See `THIRD_PARTY_NOTICES.md` for attribution and license terms.
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# SPDX-License-Identifier: CC-BY-NC-SA-3.0
|
|
4
|
+
# Adapted from Ruby Koans by Jim Weirich and Joe O'Brien.
|
|
5
|
+
# See THIRD_PARTY_NOTICES.md for attribution and license terms.
|
|
6
|
+
|
|
7
|
+
module Exercises
|
|
8
|
+
# A deterministic Greed game engine; callers supply rolls and decide when to bank.
|
|
9
|
+
class AboutExtraCredit
|
|
10
|
+
# Tracks one player and the entry threshold.
|
|
11
|
+
class Player
|
|
12
|
+
attr_reader :name, :score
|
|
13
|
+
|
|
14
|
+
# @param name [String] player name
|
|
15
|
+
def initialize(name)
|
|
16
|
+
@name = name
|
|
17
|
+
@score = 0
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Bank a turn once the player has entered with at least 300 points.
|
|
21
|
+
# @return [Integer] total score
|
|
22
|
+
# TODO: require 300 points to enter the game.
|
|
23
|
+
def bank(points)
|
|
24
|
+
@score += points
|
|
25
|
+
@score
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Coordinates turn order, banking, busts and the final round.
|
|
30
|
+
class Game
|
|
31
|
+
attr_reader :players, :current
|
|
32
|
+
|
|
33
|
+
# @param names [Array<String>] at least two players, in turn order
|
|
34
|
+
def initialize(names)
|
|
35
|
+
raise ArgumentError, 'at least two players required' if names.size < 2
|
|
36
|
+
|
|
37
|
+
@players = names.map { |name| Player.new(name) }
|
|
38
|
+
@current = 0
|
|
39
|
+
@remaining = nil
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Play the current player's complete turn; ending the rolls banks the points.
|
|
43
|
+
# @param rolls [Array<Array<Integer>>] ordered rolls, with legal remaining-dice counts
|
|
44
|
+
# @return [Integer] that player's total score after this turn
|
|
45
|
+
def play_turn(rolls)
|
|
46
|
+
raise 'game finished' if finished?
|
|
47
|
+
|
|
48
|
+
total = players[current].bank(turn_points(rolls))
|
|
49
|
+
advance(total)
|
|
50
|
+
total
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# @return [Boolean] all other players have taken their final turn
|
|
54
|
+
def finished?
|
|
55
|
+
@remaining&.zero? || false
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# @return [Player, nil] highest-scoring player after the final round; first in a tie
|
|
59
|
+
def winner
|
|
60
|
+
players.max_by(&:score) if finished?
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
private
|
|
64
|
+
|
|
65
|
+
# @return [Integer] accumulated turn points, or zero after a bust
|
|
66
|
+
def turn_points(rolls)
|
|
67
|
+
raise ArgumentError, 'a turn needs at least one roll' if rolls.empty?
|
|
68
|
+
|
|
69
|
+
points = 0
|
|
70
|
+
count = 5
|
|
71
|
+
rolls.each_with_index do |roll, index|
|
|
72
|
+
validate_roll(roll, count)
|
|
73
|
+
scored, unused = score_roll(roll)
|
|
74
|
+
if scored.zero?
|
|
75
|
+
raise ArgumentError, 'turn ends on a bust' unless index == rolls.size - 1
|
|
76
|
+
|
|
77
|
+
# TODO: a bust loses all points from this turn.
|
|
78
|
+
return points
|
|
79
|
+
end
|
|
80
|
+
points += scored
|
|
81
|
+
count = unused.zero? ? 5 : unused
|
|
82
|
+
end
|
|
83
|
+
points
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# @return [void] reject malformed rolls before changing game state
|
|
87
|
+
def validate_roll(roll, count)
|
|
88
|
+
valid = roll.size == count && roll.all? { |face| face.is_a?(Integer) && (1..6).cover?(face) }
|
|
89
|
+
raise ArgumentError, 'invalid dice count or face' unless valid
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# @return [Array<Integer>] points and the number of non-scoring dice
|
|
93
|
+
def score_roll(roll)
|
|
94
|
+
points = 0
|
|
95
|
+
unused = 0
|
|
96
|
+
roll.tally.each do |face, amount|
|
|
97
|
+
triples, singles = amount.divmod(3)
|
|
98
|
+
points += triples * (face == 1 ? 1000 : face * 100)
|
|
99
|
+
points += singles * { 1 => 100, 5 => 50 }.fetch(face, 0)
|
|
100
|
+
unused += singles unless [1, 5].include?(face)
|
|
101
|
+
end
|
|
102
|
+
[points, unused]
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
# Start the final round once, then give each remaining player exactly one turn.
|
|
106
|
+
def advance(total)
|
|
107
|
+
if @remaining
|
|
108
|
+
@remaining -= 1
|
|
109
|
+
elsif total >= 3000
|
|
110
|
+
# TODO: the other players still get a final turn.
|
|
111
|
+
@remaining = 0
|
|
112
|
+
end
|
|
113
|
+
@current = (current + 1) % players.size
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Extra Credit
|
|
2
|
+
|
|
3
|
+
The original extra-credit chapter proposes a free-form Greed game. This adaptation
|
|
4
|
+
provides a deterministic engine to repair in `about_extra_credit.rb`; a terminal
|
|
5
|
+
interface or computer player remains an optional extension.
|
|
6
|
+
|
|
7
|
+
Fix the three incomplete rules in `Player#bank`, `Game#turn_points`, and
|
|
8
|
+
`Game#advance`. Supplied scoring follows the scoring project: triples of ones
|
|
9
|
+
are 1000, other triples are 100 times the face, remaining ones are 100 and
|
|
10
|
+
fives are 50. Dice count once per roll.
|
|
11
|
+
|
|
12
|
+
`Game.new(names)` requires at least two players. `play_turn(rolls)` accepts all
|
|
13
|
+
rolls for the current player and returns their total score. The first roll uses
|
|
14
|
+
five dice; later rolls use only non-scoring dice, or five again when all scored.
|
|
15
|
+
Ending the supplied rolls means banking. A zero-point roll ends the turn and
|
|
16
|
+
loses its accumulated points, preserving earlier banked totals. A player must
|
|
17
|
+
first bank at least 300 in one turn; smaller turns count after entry.
|
|
18
|
+
|
|
19
|
+
Reaching 3000 starts the final round: every other player gets exactly one more
|
|
20
|
+
turn, even if someone overtakes the leader. `finished?` then becomes true and
|
|
21
|
+
`winner` returns the highest-scoring Player (first in turn order on a tie).
|
|
22
|
+
Reject further turns. Malformed rolls raise `ArgumentError` without advancing
|
|
23
|
+
the game. Example: `[[1, 5, 2, 3, 4], [2, 2, 2]]` banks 350 points.
|
|
24
|
+
|
|
25
|
+
Rolls are inputs so the game can be checked reproducibly. You can connect it to
|
|
26
|
+
your DiceSet and a human or automated decision-maker as an optional extension.
|
|
27
|
+
|
|
28
|
+
Adapted from Ruby Koans by Jim Weirich and Joe O'Brien, licensed under CC BY-NC-SA 3.0. See `THIRD_PARTY_NOTICES.md`.
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# SPDX-License-Identifier: CC-BY-NC-SA-3.0
|
|
4
|
+
# Adapted from Ruby Koans by Jim Weirich and Joe O'Brien.
|
|
5
|
+
# See THIRD_PARTY_NOTICES.md for attribution and license terms.
|
|
6
|
+
|
|
7
|
+
module Exercises
|
|
8
|
+
# Predictions for hashes examples.
|
|
9
|
+
class AboutHashes
|
|
10
|
+
# Replace each :fill_me_in with the result of the described expression.
|
|
11
|
+
# @return [Hash<Symbol, Object>]
|
|
12
|
+
# This method is an answer table, not a sequence of operations.
|
|
13
|
+
def self.koans # rubocop:disable Metrics/MethodLength
|
|
14
|
+
{
|
|
15
|
+
# Creating hashes.
|
|
16
|
+
# empty_hash = Hash.new
|
|
17
|
+
# assert_equal __, empty_hash.class
|
|
18
|
+
# assert_equal(__, empty_hash)
|
|
19
|
+
# assert_equal __, empty_hash.size
|
|
20
|
+
# Predict: empty_hash.class
|
|
21
|
+
creating_hashes_one: :fill_me_in,
|
|
22
|
+
# Predict: empty_hash
|
|
23
|
+
creating_hashes_two: :fill_me_in,
|
|
24
|
+
# Predict: empty_hash.size
|
|
25
|
+
creating_hashes_three: :fill_me_in,
|
|
26
|
+
# Hash literals.
|
|
27
|
+
# hash = { :one => "uno", :two => "dos" }
|
|
28
|
+
# assert_equal __, hash.size
|
|
29
|
+
# Predict: hash.size
|
|
30
|
+
hash_literals_one: :fill_me_in,
|
|
31
|
+
# Accessing hashes.
|
|
32
|
+
# hash = { :one => "uno", :two => "dos" }
|
|
33
|
+
# assert_equal __, hash[:one]
|
|
34
|
+
# assert_equal __, hash[:two]
|
|
35
|
+
# assert_equal __, hash[:doesnt_exist]
|
|
36
|
+
# Predict: hash[:one]
|
|
37
|
+
accessing_hashes_one: :fill_me_in,
|
|
38
|
+
# Predict: hash[:two]
|
|
39
|
+
accessing_hashes_two: :fill_me_in,
|
|
40
|
+
# Predict: hash[:doesnt_exist]
|
|
41
|
+
accessing_hashes_three: :fill_me_in,
|
|
42
|
+
# Accessing hashes with fetch.
|
|
43
|
+
# hash = { :one => "uno" }
|
|
44
|
+
# assert_equal __, hash.fetch(:one)
|
|
45
|
+
# assert_raise(___) do
|
|
46
|
+
# hash.fetch(:doesnt_exist)
|
|
47
|
+
# end
|
|
48
|
+
# Predict: hash.fetch(:one)
|
|
49
|
+
accessing_hashes_with_fetch_one: :fill_me_in,
|
|
50
|
+
# Predict: exception class from: hash.fetch(:doesnt_exist)
|
|
51
|
+
accessing_hashes_with_fetch_two: :fill_me_in,
|
|
52
|
+
# Changing hashes.
|
|
53
|
+
# hash = { :one => "uno", :two => "dos" }
|
|
54
|
+
# hash[:one] = "eins"
|
|
55
|
+
# assert_equal __, hash
|
|
56
|
+
# Predict: hash
|
|
57
|
+
changing_hashes_one: :fill_me_in,
|
|
58
|
+
# Hash is unordered.
|
|
59
|
+
# hash1 = { :one => "uno", :two => "dos" }
|
|
60
|
+
# hash2 = { :two => "dos", :one => "uno" }
|
|
61
|
+
# assert_equal __, hash1 == hash2
|
|
62
|
+
# Predict: hash1 == hash2
|
|
63
|
+
hash_is_unordered_one: :fill_me_in,
|
|
64
|
+
# Hash keys.
|
|
65
|
+
# hash = { :one => "uno", :two => "dos" }
|
|
66
|
+
# assert_equal __, hash.keys.size
|
|
67
|
+
# assert_equal __, hash.keys.include?(:one)
|
|
68
|
+
# assert_equal __, hash.keys.include?(:two)
|
|
69
|
+
# assert_equal __, hash.keys.class
|
|
70
|
+
# Predict: hash.keys.size
|
|
71
|
+
hash_keys_one: :fill_me_in,
|
|
72
|
+
# Predict: hash.keys.include?(:one)
|
|
73
|
+
hash_keys_two: :fill_me_in,
|
|
74
|
+
# Predict: hash.keys.include?(:two)
|
|
75
|
+
hash_keys_three: :fill_me_in,
|
|
76
|
+
# Predict: hash.keys.class
|
|
77
|
+
hash_keys_four: :fill_me_in,
|
|
78
|
+
# Hash values.
|
|
79
|
+
# hash = { :one => "uno", :two => "dos" }
|
|
80
|
+
# assert_equal __, hash.values.size
|
|
81
|
+
# assert_equal __, hash.values.include?("uno")
|
|
82
|
+
# assert_equal __, hash.values.include?("dos")
|
|
83
|
+
# assert_equal __, hash.values.class
|
|
84
|
+
# Predict: hash.values.size
|
|
85
|
+
hash_values_one: :fill_me_in,
|
|
86
|
+
# Predict: hash.values.include?("uno")
|
|
87
|
+
hash_values_two: :fill_me_in,
|
|
88
|
+
# Predict: hash.values.include?("dos")
|
|
89
|
+
hash_values_three: :fill_me_in,
|
|
90
|
+
# Predict: hash.values.class
|
|
91
|
+
hash_values_four: :fill_me_in,
|
|
92
|
+
# Combining hashes.
|
|
93
|
+
# hash = { "jim" => 53, "amy" => 20, "dan" => 23 }
|
|
94
|
+
# new_hash = hash.merge({ "jim" => 54, "jenny" => 26 })
|
|
95
|
+
# assert_equal __, hash != new_hash
|
|
96
|
+
# expected = { "jim" => 54, "amy" => 20, "dan" => 23, "jenny" => 26 }
|
|
97
|
+
# assert_equal __, expected == new_hash
|
|
98
|
+
# Predict: hash != new_hash
|
|
99
|
+
combining_hashes_one: :fill_me_in,
|
|
100
|
+
# Predict: expected == new_hash
|
|
101
|
+
combining_hashes_two: :fill_me_in,
|
|
102
|
+
# Default value.
|
|
103
|
+
# hash1 = Hash.new
|
|
104
|
+
# hash1[:one] = 1
|
|
105
|
+
# assert_equal __, hash1[:one]
|
|
106
|
+
# assert_equal __, hash1[:two]
|
|
107
|
+
# hash2 = Hash.new("dos")
|
|
108
|
+
# hash2[:one] = 1
|
|
109
|
+
# assert_equal __, hash2[:one]
|
|
110
|
+
# assert_equal __, hash2[:two]
|
|
111
|
+
# Predict: hash1[:one]
|
|
112
|
+
default_value_one: :fill_me_in,
|
|
113
|
+
# Predict: hash1[:two]
|
|
114
|
+
default_value_two: :fill_me_in,
|
|
115
|
+
# Predict: hash2[:one]
|
|
116
|
+
default_value_three: :fill_me_in,
|
|
117
|
+
# Predict: hash2[:two]
|
|
118
|
+
default_value_four: :fill_me_in,
|
|
119
|
+
# Default value is the same object.
|
|
120
|
+
# hash = Hash.new([])
|
|
121
|
+
# hash[:one] << "uno"
|
|
122
|
+
# hash[:two] << "dos"
|
|
123
|
+
# assert_equal __, hash[:one]
|
|
124
|
+
# assert_equal __, hash[:two]
|
|
125
|
+
# assert_equal __, hash[:three]
|
|
126
|
+
# assert_equal __, hash[:one].equal?(hash[:two])
|
|
127
|
+
# Predict: hash[:one]
|
|
128
|
+
default_value_is_the_same_object_one: :fill_me_in,
|
|
129
|
+
# Predict: hash[:two]
|
|
130
|
+
default_value_is_the_same_object_two: :fill_me_in,
|
|
131
|
+
# Predict: hash[:three]
|
|
132
|
+
default_value_is_the_same_object_three: :fill_me_in,
|
|
133
|
+
# Predict: hash[:one].equal?(hash[:two])
|
|
134
|
+
default_value_is_the_same_object_four: :fill_me_in,
|
|
135
|
+
# Default value with block.
|
|
136
|
+
# hash = Hash.new {|hash, key| hash[key] = [] }
|
|
137
|
+
# hash[:one] << "uno"
|
|
138
|
+
# hash[:two] << "dos"
|
|
139
|
+
# assert_equal __, hash[:one]
|
|
140
|
+
# assert_equal __, hash[:two]
|
|
141
|
+
# assert_equal __, hash[:three]
|
|
142
|
+
# Predict: hash[:one]
|
|
143
|
+
default_value_with_block_one: :fill_me_in,
|
|
144
|
+
# Predict: hash[:two]
|
|
145
|
+
default_value_with_block_two: :fill_me_in,
|
|
146
|
+
# Predict: hash[:three]
|
|
147
|
+
default_value_with_block_three: :fill_me_in,
|
|
148
|
+
# Default value attribute.
|
|
149
|
+
# hash = Hash.new
|
|
150
|
+
# assert_equal __, hash[:some_key]
|
|
151
|
+
# hash.default = 'peanut'
|
|
152
|
+
# assert_equal __, hash[:some_key]
|
|
153
|
+
# Predict: hash[:some_key]
|
|
154
|
+
default_value_attribute_one: :fill_me_in,
|
|
155
|
+
# Predict: hash[:some_key]
|
|
156
|
+
default_value_attribute_two: :fill_me_in
|
|
157
|
+
}
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
end
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# About Hashes
|
|
2
|
+
|
|
3
|
+
Replace each `:fill_me_in` in `about_hashes.rb` with the predicted result.
|
|
4
|
+
Each field identifies its example. Run the checks after edits to investigate the
|
|
5
|
+
next prediction. Answers include the Ruby values and exception classes shown by
|
|
6
|
+
the examples. Read the setup comments before evaluating an expression.
|
|
7
|
+
|
|
8
|
+
Adapted from Ruby Koans by Jim Weirich and Joe O'Brien, licensed under
|
|
9
|
+
CC BY-NC-SA 3.0. See `THIRD_PARTY_NOTICES.md` for attribution and license terms.
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# Hint
|
|
2
|
+
|
|
3
|
+
Compare `hash[key]` with `hash.fetch(key)` for an absent key.
|
|
4
|
+
A shared default object is reused; a default block can create and store a fresh
|
|
5
|
+
value for each key. Merging returns a new hash; inspect both hashes afterward.
|
|
6
|
+
|
|
7
|
+
Adapted from Ruby Koans by Jim Weirich and Joe O'Brien, licensed under
|
|
8
|
+
CC BY-NC-SA 3.0. See `THIRD_PARTY_NOTICES.md` for attribution and license terms.
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# SPDX-License-Identifier: CC-BY-NC-SA-3.0
|
|
4
|
+
# Adapted from Ruby Koans by Jim Weirich and Joe O'Brien.
|
|
5
|
+
# See THIRD_PARTY_NOTICES.md for attribution and license terms.
|
|
6
|
+
|
|
7
|
+
module Exercises
|
|
8
|
+
# Predictions for inheritance examples.
|
|
9
|
+
class AboutInheritance
|
|
10
|
+
# Replace each :fill_me_in with the result of the described expression.
|
|
11
|
+
# @return [Hash<Symbol, Object>]
|
|
12
|
+
# This method is an answer table, not a sequence of operations.
|
|
13
|
+
def self.koans
|
|
14
|
+
{
|
|
15
|
+
# Subclasses have the parent as an ancestor.
|
|
16
|
+
# assert_equal __, Chihuahua.ancestors.include?(Dog)
|
|
17
|
+
# Predict: Chihuahua.ancestors.include?(Dog)
|
|
18
|
+
subclasses_have_the_parent_as_an_ancestor_one: :fill_me_in,
|
|
19
|
+
# All classes ultimately inherit from object.
|
|
20
|
+
# assert_equal __, Chihuahua.ancestors.include?(Object)
|
|
21
|
+
# Predict: Chihuahua.ancestors.include?(Object)
|
|
22
|
+
all_classes_ultimately_inherit_from_object_one: :fill_me_in,
|
|
23
|
+
# Subclasses inherit behavior from parent class.
|
|
24
|
+
# chico = Chihuahua.new("Chico")
|
|
25
|
+
# assert_equal __, chico.name
|
|
26
|
+
# Predict: chico.name
|
|
27
|
+
subclasses_inherit_behavior_from_parent_class_one: :fill_me_in,
|
|
28
|
+
# Subclasses add new behavior.
|
|
29
|
+
# chico = Chihuahua.new("Chico")
|
|
30
|
+
# assert_equal __, chico.wag
|
|
31
|
+
# assert_raise(___) do
|
|
32
|
+
# fido = Dog.new("Fido")
|
|
33
|
+
# fido.wag
|
|
34
|
+
# end
|
|
35
|
+
# Predict: chico.wag
|
|
36
|
+
subclasses_add_new_behavior_one: :fill_me_in,
|
|
37
|
+
# Predict: exception class from: fido = Dog.new("Fido"); fido.wag
|
|
38
|
+
subclasses_add_new_behavior_two: :fill_me_in,
|
|
39
|
+
# Subclasses can modify existing behavior.
|
|
40
|
+
# chico = Chihuahua.new("Chico")
|
|
41
|
+
# assert_equal __, chico.bark
|
|
42
|
+
# fido = Dog.new("Fido")
|
|
43
|
+
# assert_equal __, fido.bark
|
|
44
|
+
# Predict: chico.bark
|
|
45
|
+
subclasses_can_modify_existing_behavior_one: :fill_me_in,
|
|
46
|
+
# Predict: fido.bark
|
|
47
|
+
subclasses_can_modify_existing_behavior_two: :fill_me_in,
|
|
48
|
+
# Subclasses can invoke parent behavior via super.
|
|
49
|
+
# ralph = BullDog.new("Ralph")
|
|
50
|
+
# assert_equal __, ralph.bark
|
|
51
|
+
# Predict: ralph.bark
|
|
52
|
+
subclasses_can_invoke_parent_behavior_via_super_one: :fill_me_in,
|
|
53
|
+
# Super does not work cross method.
|
|
54
|
+
# george = GreatDane.new("George")
|
|
55
|
+
# assert_raise(___) do
|
|
56
|
+
# george.growl
|
|
57
|
+
# end
|
|
58
|
+
# Predict: exception class from: george.growl
|
|
59
|
+
super_does_not_work_cross_method_one: :fill_me_in
|
|
60
|
+
}
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# About Inheritance
|
|
2
|
+
|
|
3
|
+
Replace each `:fill_me_in` in `about_inheritance.rb` with the predicted result.
|
|
4
|
+
Each field identifies its example. Run the checks after edits to investigate the
|
|
5
|
+
next prediction. Answers include the Ruby values and exception classes shown by
|
|
6
|
+
the examples. Read the setup comments before evaluating an expression.
|
|
7
|
+
|
|
8
|
+
## Example definitions
|
|
9
|
+
|
|
10
|
+
These definitions supply the objects and methods used by the prediction examples.
|
|
11
|
+
They run in the check class `AboutInheritanceTest`.
|
|
12
|
+
|
|
13
|
+
```ruby
|
|
14
|
+
class Dog
|
|
15
|
+
attr_reader :name
|
|
16
|
+
|
|
17
|
+
def initialize(name)
|
|
18
|
+
@name = name
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def bark
|
|
22
|
+
"WOOF"
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
class Chihuahua < Dog
|
|
27
|
+
def wag
|
|
28
|
+
:happy
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def bark
|
|
32
|
+
"yip"
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
class BullDog < Dog
|
|
37
|
+
def bark
|
|
38
|
+
super + ", GROWL"
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
class GreatDane < Dog
|
|
43
|
+
def growl
|
|
44
|
+
super.bark + ", GROWL"
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Adapted from Ruby Koans by Jim Weirich and Joe O'Brien, licensed under
|
|
50
|
+
CC BY-NC-SA 3.0. See `THIRD_PARTY_NOTICES.md` for attribution and license terms.
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# Hint
|
|
2
|
+
|
|
3
|
+
Look at the receiver class and its ancestors. `super` invokes the same method
|
|
4
|
+
name further up the lookup chain; it does not search for a differently named
|
|
5
|
+
method on the parent.
|
|
6
|
+
|
|
7
|
+
Adapted from Ruby Koans by Jim Weirich and Joe O'Brien, licensed under
|
|
8
|
+
CC BY-NC-SA 3.0. See `THIRD_PARTY_NOTICES.md` for attribution and license terms.
|