TUTORIAL.md in contracts-0.5 vs TUTORIAL.md in contracts-0.6
- old
+ new
@@ -403,12 +403,14 @@
If you want to disable contracts, set the `NO_CONTRACTS` environment variable. This will disable contracts completely and you won't have a performance hit.
## Method overloading
-You can use contracts for method overloading! For example, here's a factorial function without method overloading:
+You can use contracts for method overloading! This is commonly called "pattern matching" in functional programming languages.
+For example, here's a factorial function without method overloading:
+
```ruby
Contract Num => Num
def fact x
if x == 1
x
@@ -431,9 +433,48 @@
x * fact(x - 1)
end
```
For an argument, each function will be tried in order. The first function that doesn't raise a `ContractError` will be used. So in this case, if x == 1, the first function will be used. For all other values, the second function will be used.
+
+This allows you write methods more declaratively, rather than using conditional branching. This feature is not only useful for recursion; you can use it to keep parallel use cases separate:
+
+```ruby
+Contract And[Num, lambda{|n| n < 12 }] => Ticket
+def get_ticket(age)
+ ChildTicket.new(age: age)
+end
+
+Contract And[Num, lambda{|n| n >= 12 }] => Ticket
+def get_ticket(age)
+ AdultTicket.new(age: age)
+end
+
+```
+
+Note that the second `get_ticket` contract above could have been simplified to:
+
+```ruby
+Contract Num => Ticket
+```
+
+This is because the first contract eliminated the possibility of `age` being less than 12. However, the simpler contract is less explicit; you may want to "spell out" the age condition for clarity, especially if the method is overloaded with many contracts.
+
+## Contracts in modules
+
+To use contracts on module you need to include both `Contracts` and `Contracts::Modules` into it:
+
+```ruby
+module M
+ include Contracts
+ include Contracts::Modules
+
+ Contract String => String
+ def self.parse
+ # do some hard parsing
+ end
+end
+```
## Invariants
Invariants are conditions on objects that should always hold. If after any method call on given object, any of the Invariants fails, then Invariant violation error will be generated.