TUTORIAL.md in contracts-0.6 vs TUTORIAL.md in contracts-0.7
- old
+ new
@@ -27,18 +27,21 @@
Copy this code into a file and run it:
```ruby
require 'contracts'
-include Contracts
-Contract Num, Num => Num
-def add(a, b)
- a + b
+class Math
+ include Contracts
+
+ Contract Num, Num => Num
+ def self.add(a, b)
+ a + b
+ end
end
-puts add(1, "foo")
+puts Math.add(1, "foo")
```
You'll see a detailed error message like so:
./contracts.rb:60:in `failure_callback': Contract violation: (RuntimeError)
@@ -58,11 +61,11 @@
This can be useful if you're in a repl and want to figure out how a function should be used.
## Builtin Contracts
-`Num` is one of the builtin contracts that contracts.ruby comes with. The builtin contracts are in the `Contracts` namespace. The easiest way to use them is to put `include Contracts` at the top of your file, but beware that they will pollute your namespace with new class names.
+`Num` is one of the builtin contracts that contracts.ruby comes with. The builtin contracts are in the `Contracts` namespace. The easiest way to use them is to include the `Contracts` module in your class/module.
contracts.ruby comes with a lot of builtin contracts, including:
Num, Pos, Neg, Any, None, Or, Xor, And, Not, RespondTo, Send, Exactly, ArrayOf, HashOf, Bool, Maybe
@@ -399,11 +402,11 @@
If your failure callback returns `false`, the method that the contract is guarding will not be called (the default behaviour).
## Disabling contracts
-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.
+If you want to disable contracts, set the `NO_CONTRACTS` environment variable. This will disable contracts and you won't have a performance hit. Pattern matching will still work if you disable contracts in this way! With NO_CONTRACTS only pattern-matching contracts are defined.
## Method overloading
You can use contracts for method overloading! This is commonly called "pattern matching" in functional programming languages.
@@ -437,16 +440,16 @@
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
+Contract lambda{|n| n < 12 } => Ticket
def get_ticket(age)
ChildTicket.new(age: age)
end
-Contract And[Num, lambda{|n| n >= 12 }] => Ticket
+Contract lambda{|n| n >= 12 } => Ticket
def get_ticket(age)
AdultTicket.new(age: age)
end
```
@@ -484,10 +487,10 @@
A simple example:
```ruby
class MyBirthday < Struct.new(:day, :month)
include Contracts
- include Contracts:Invariants
+ include Contracts::Invariants
Invariant(:day) { 1 <= day && day <= 31 }
Invariant(:month) { 1 <= month && month <= 12 }
Contract None => Fixnum