diff --git a/features/advanced/pattern_matching.feature b/features/advanced/pattern_matching.feature new file mode 100644 index 0000000..20289ca --- /dev/null +++ b/features/advanced/pattern_matching.feature @@ -0,0 +1,104 @@ +Feature: Method Overloading + + You can use contracts for method overloading! This is commonly called "pattern matching" in functional programming languages. + + ```ruby + Contract 1 => 1 + def fact x + x + end + + Contract C::Num => C::Num + def fact x + x * fact(x - 1) + end + ``` + + Background: + Given a file named "method_overloading_with_positional_args_usage.rb" with: + """ruby + require "contracts" + C = Contracts + + class Example + include Contracts::Core + + Contract 1 => 1 + def fact(x) + x + end + + Contract C::Num => C::Num + def fact(x) + x * fact(x - 1) + end + end + """ + + Given a file named "method_overloading_with_keyword_args_usage.rb" with: + """ruby + require "contracts" + C = Contracts + + class Example + include Contracts::Core + + Contract C::KeywordArgs[age: Integer, size: Symbol] => String + def speak(age:, size:) + "age: #{age} size: #{size}" + end + + Contract C::KeywordArgs[sound: String] => String + def speak(sound:) + "sound: #{sound}" + end + end + """ + + Scenario: Positional Args Method 1 + Given a file named "positional_args_method_1.rb" with: + """ruby + require "./method_overloading_with_positional_args_usage" + puts Example.new.fact(1) + """ + When I run `ruby positional_args_method_1.rb` + Then the output should contain: + """ + 1 + """ + + Scenario: Positional Args Method 2 + Given a file named "positional_args_method_2.rb" with: + """ruby + require "./method_overloading_with_positional_args_usage" + puts Example.new.fact(4) + """ + When I run `ruby positional_args_method_2.rb` + Then the output should contain: + """ + 24 + """ + + Scenario: Keyword Args Method 1 + Given a file named "keyword_args_method_1.rb" with: + """ruby + require "./method_overloading_with_keyword_args_usage" + puts Example.new.speak(age: 5, size: :large) + """ + When I run `ruby keyword_args_method_1.rb` + Then the output should contain: + """ + age: 5 size: large + """ + + Scenario: Keyword Args Method 2 + Given a file named "keyword_args_method_2.rb" with: + """ruby + require "./method_overloading_with_keyword_args_usage" + puts Example.new.speak(sound: "woof") + """ + When I run `ruby keyword_args_method_2.rb` + Then the output should contain: + """ + sound: woof + """ diff --git a/lib/contracts/method_handler.rb b/lib/contracts/method_handler.rb index 5378e6a..1d683e2 100644 --- a/lib/contracts/method_handler.rb +++ b/lib/contracts/method_handler.rb @@ -174,8 +174,10 @@ def foo x def validate_pattern_matching! new_args_contract = decorator.args_contracts + new_kargs_contract = decorator.kargs_contract matched = decorated_methods.select do |contract| - contract.args_contracts == new_args_contract + contract.args_contracts == new_args_contract && + contract.kargs_contract == new_kargs_contract end return if matched.empty?